运算符与类型转换

运算符

作用:操作变量

名称

符号

算术

++、--、+、-、*、/、%

赋值

=、+=、-=、*=、/=、%=

关系

>、<、>=、<=、==、!=、instanceof

逻辑

&、|、&&、||、!、^

&、|、^、~、<<、>>、>>>

条件/三元

? :

字符串连接符

+

首先说下重点是关系/逻辑/三元运算符,难点是位运算符,学透原码反码补码才能更好的理解位运算符。

算术运算符

算术运算,结果为一个数值。见下表:

运算符

说明

举例

+

加法

1 + 2

-

减法

4 - 3.4

*

乘法

7 * 1.5

/

除法

3.5 / 7

%

取余

7 % 2

++

自增

3++

--

自减

3--

概述:简单的加减乘除商和加加减减。

难点:++和--就是加1或减1。++和—可以作为独立语句使用,且内部做自动强转优化。

注意:byte b = 2; b = b+1需要强转b = (byte)(b+1);b++底层会自动强转,所以不会报错。

赋值运算符

概述:(基本赋值)=,复合赋值:+=、-=、*=、/=、%=,比如:a+=b等同于a=a+b且内部有做优化,其它符号效果一样。

关系运算符

关系运算符,结果为一个布尔值。见下表:

运算符

说明

举例

>

大于

a > 4.2

>=

大于等于

3.4 >= b

<

小于

1.5 < 9

<=

小于等于

6 <= 1

==

等于

2 == 2

!=

不等于

2 != 2

&&

true && false

||

(3 > 1) || (2 == 1)

!

!true

逻辑运算符

概述:>、<、>=、<=、==、!=、instanceof。做比较运算,结果是boolean类型。也叫比较运算符。instanceof:判断对象类型。

概述:&、|、&&、||、!、^,两个业务逻辑做运算

  • & 与:有false为false。只要有一边值为false,结果为false

  • |或:有true为true。只要有一边值为true,结果为true

  • &&短路与:左false,右不执行

  • ||短路或:左true,右不执行

简单来讲 &、|和的区别是,当&&、||左边的值为f/t时,右边的值不运算,直接给出false/true。

  • !非:非真既假,非假既真。!true结果为false,!false结果为true

  • ^异或:同真异假。两边结果同时【一同为真或一同为假】一直为真,反之即为假。

位/位移运算符

位运算符对整数的二进制形式逐位进行逻辑运算,得到一个整数。见下表:

运算符

说明

举例

&

1 & 4

|

2 | 5

^

异或

2 ^ 3

~

~5

<<

左移

5 << 3

>>

右移

6 >> 1

概述:&、|、^、~、<<、>>、>>>

运算规则:计算机是二进制,所有数据都是0和1组成。先假设0为false,1为true。

  • &(位与): 有0则0

  • |(位或): 有1则1

  • ^(位异或): 相同为0(0^0或1^1)不同为1(1^0或0^1)

  • ~(位反码或者按位取反): 0变1,1变0(无论是符号位还是数值位都需要发生改变)

^的特点:一个数据被另一个数据位异或两次,该数本身不变。

  • <<:把<<左边的数乘以2的移动次幂,也就是向左位移两位。// 3<<4 3 * 16 = 48

  • >>:把>>左边的数除以2的移动次幂,也就是向右位移两位。// 88>>3 88 / 8 = 11

  • >>>:表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0。

>>是若该数为负数,则右移后高位补1。

比如:“-8>>2 -8/2*2 = -4”“-8>>>2 = 1073741822”

左移,相当于 两次乘2 , 右移,相当于 两次除2(不够除,只取整数部分)

举例:

数值

机器码(8字节显示)

最终值

3

0000 0011

3

5

0000 0101

5

3&5

0000 0001

1

3|5

0000 0111

7

3^5

0000 1001

9

~3

1000 0100(原码)

-4

~5

1000 0110(原码)

-6

9

0000 1001

9

9^3

0000 0101

5

5^3^3:5^3的值为0000 1001,也就是数字9,9^3=000 0101,也就是数字5。

条件/三元运算符

Java中也有一个条件运算符(三目运算符):

condition ? x1 : x2

condition为一个boolean值。根据condition,取x1或x2的值。

注意:表达式1、2两边的类型必须一致或者兼容(可以直接转)。

x为 boolean 类型表达式,true执行y,alse执行z。

int result = 10>2 ? 100:200;  
System.out.println(result);

字符串连接符

“+”运算符两侧的操作数中只要有一个是String类型,系统会自动将另一个操作数转换为字符串然后再进行连接。运算符中的“+”是唯一比较特殊的。

System.out.println("1"+2+3+4);// 1234  
System.out.println(1+"1"+2+3+4);// 11234  
System.out.println(1+2+"1"+2+3+4);// 31234  
System.out.println(‘男’ + ‘女’); // 结果为整数,因为字符的底层为整数。

遇到字符串之后的所有值(不管是数值/字符/boolean…)会转换成字符串。

连接符优选级

建议:

  • 1.不用刻意去记,表达式优先使用()表示。

  • 2.&>|>![与或非]是重点。如:a||b&&c运算结果是a||(b&&c)

运算符优先级:

优先级

运算符

运算符类型

综合性

1

()

括号

由左到右

2

!、+、-

一元

由左到右

2

~

由右到左

2

++、--

算术

由右到左

3

*、/、%

算术

由左到右

4

+、-

算术

由左到右

5

<<、>>

由左到右

6

<、<=、>、>=

关系

由左到右

7

==、!=

关系

由左到右

8

&

位、逻辑

由左到右

9

^

位、逻辑

由左到右

10

|

位、逻辑

由左到右

11

&&

逻辑

由左到右

12

||

逻辑

由左到右

13

?:

条件

由右到左

14

=、+=、-=、*=、/=、%=

逻辑

由右到左

示例:

public class Demo {
    public static void main(String[] args){
        int a=10;
        int b=10;

        int x=10;
        int y=21;
        int z=10;

        System.out.println("后自加 a=" + (a++));
        System.out.println("a的值 a=" + a);
        System.out.println("前自加 b=" + (++b));

        System.out.println("---------------------");
        System.out.println("说 x>y,对吗?" + (x>y));
        System.out.println("认为 x>y 并且 x<y,对吗?" + ( (x>y) && (x<y) ));
        System.out.println("认为 x>=y 或者 x==y,对吗?" + ( (x>=y) || (x==y) ));
        System.out.println("认为 x<y 或者 x=z,对吗?" + ( (x<y) || (x==z) ));
        System.out.println("---------------------");
        System.out.println("a&x 的结果是:" + (a&x));
        System.out.println("a|x 的结果是:" + (a|x));
        System.out.println("y^z 的结果是:" + (y^z));

        System.out.println("---------------------");
        System.out.println("a 左移2位的结果是:" + (a<<2));
        System.out.println("y 右移3位的结果是:" + (y>>3));
    }
}

运行结果:

后自加 a=10
a的值 a=11
前自加 b=11
---------------------
说 x>y,对吗?false
认为 x>y 并且 x<y,对吗?false
认为 x>=y 或者 x==y,对吗?false
认为 x<y 或者 x=z,对吗?true
---------------------
a&x 的结果是:10
a|x 的结果是:11
y^z 的结果是:31
---------------------
a 左移2位的结果是:44
y 右移3位的结果是:2

类型转换

目的:防止精度损失(为什么会有精度损失情况原码反码补码章节)

分类:自动类型转换和强制类型转换。

自动类型转换(从小到大):容量小的数据类型可自动转换为容量大的数据类型。下图所示,实线表示无数据丢失的自动类型转换,而虚线表示在转换时可能会有精度的损失。

boolean类型不能转换为其他的数据类型。与其它7个类型不兼容。

byte,short,char — int — long — float — double。

byte,short,char之间不相互转换,直接转成int类型参与运算。

强制类型转换(从大到小):

格式:(type)variable,运算符“()”中的type表示将值var想要转换成的目标数据类型

场景:

double d  = 3.14;   
int i = (int)d;   //值为3,只有整数位的值,小数点位的值不管多大都不显示。

规则:

自动提升原则:表达式的结果类型为 操作数中类型最大的,如1.5f+2的类型就是float。

强转符号只针对于最近的变量有效‘’

byte和short会以int进行运算,所以byte a=1;a=a+1;必须为a=(byte)(a+1);

char类型的值可以是int的常量值,但不可以是int的变量值,需要强转。

Last updated

Was this helpful?