Java操作符包括:算术操作符、赋值操作符、按位操作符(这些都带有运算功能,又叫运算符),除了这些还有new(创建对象的)、转型操作符cast(type)、intstanceof(统计子类数量)等,这里我们主要介绍的是运算符。
运算符的优先级
注:右结合:是从右向左计算;左结合性:是从左向右计算。
赋值操作符
赋值操作符具有右结合性,从右向左操作。
算术操作符
Java中的算术运算符使用和C/C++中类似:
public class Main{
public static void main(String[] args){
int a = 15;
int b = 4;
//一元操作符
//正号作用:将小类型的操作符提升为int
//符号作用:标记负数
System.out.println("正号作用:"+(+'A'));
System.out.println("a++是先打印再自己加1:"+(a++));
System.out.println("++a是先自己加1在打印:"+(++a));
System.out.println("b--是先打印再自己减1:"+(b--));
System.out.println("--b是先自己减1在打印:"+(--b));
//二元操作符
System.out.println("a+b:"+(a+b));
System.out.println("a-b:"+(a-b));
System.out.println("a*b:"+(a*b));
System.out.println("a/b:"+(a/b));
System.out.println("a%b:"+(a%b));
//复合运算符
System.out.println("a += b 等价 a = a + b:"+(a += b));
System.out.println("a -= b 等价 a = a - b:"+(a -= b));
System.out.println("a *= b 等价 a = a * b:"+(a *= b));
System.out.println("a %= b 等价 a = a % b;"+(a %= b));
System.out.println("a /= b 等价 a = a / b:"+(a /= b));
}
}
//output:
正号作用:65
a++是先打印再自己加1:15
++a是先自己加1在打印:17
b--是先打印再自己减1:4
--b是先自己减1在打印:2
a+b:19
a-b:15
a*b:34
a/b:8
a%b:1
a += b 等价 a = a + b:19
a -= b 等价 a = a - b:17
a *= b 等价 a = a * b:34
a %= b 等价 a = a % b;0
a /= b 等价 a = a / b:0
Tips: 负数%负数为负(或0),正数%正数为正(或0);负数%正数为负,正数%负数为负
- 运算符重载现象
Java也有和 C++ 的运算符重载,只不过Java只支持 +
和 +=
重载且不支持自己重载运算,Java重载运算符作用是为了字符串连接。
public class Main{
public static void main(String[] args){
String a = "hello";
String b = "world";
System.out.println(a+' '+b);
a += b;
System.out.println(a);
a = "hello"+' '+ 'w' + 'r' + "old" + ' ' + 41 + "愚人节";
System.out.println(a);
}
}
//output:
hello world
helloworld
hello wrold 41愚人节
Tips:如果表达式是以字符串开头,后续所有操作数会自动转换为字符串进行连接。
拓展:如何对表达式中的算术表达式先运算再进行连接
public class Main{
public static void main(String[] args){
int a = 41;
int b = 52;
System.out.println("a+b="+ a + b); //这样只会进行连接,而不会计算a+b
System.out.println("a+b="+ (a + b)); //加个括号,表示算术运算优先运算
}
}
//Output:
a+b=4152
a+b=93
关系操作符
例如:比较两个对象是否相同。
public class Main{
public static void main(String[] args){
String s1 = "hha";
String s2 = new String(s1);
String s3 = s1;
System.out.println("s1 == s2 ? " + (s1 == s2));
System.out.println("s1 equals(s2) ?" + (s1.equals(s2)));
System.out.println("s1 == s3 ? " + (s1 == s3));
System.out.println("s1 equals(s3) ?" + (s1.equals(s3)));
//equals方法比较的是对象的引用
//== 必须两个对象一模一样才返回true,即两个对象的别名一定 ==
}
}
//Output:
s1 == s2 ? false
s1 equals(s2) ?true
s1 == s3 ? true
s1 equals(s3) ?true
Tips:由于String创建方式的不同,会影响String对象的引用指向。
三元操作符
value0和value1既可以是值也可以是表达式,布尔表达式为真执行value0;布尔表达式为假执行value1;功能同 if-else
public class Assignment{
public static void main(String[] args){
System.out.println(13 == 12 ? "我是不对的" : "我是对的");
}
}
//Output:
我是对的
逻辑操作符
在C和C++中,逻辑操作符的操作数可以是整数(认为非0数为true,0为false),但是,在Java中,逻辑运算符的操作数只允许是布尔类型的。
public class Main{
public static void main(String[] args){
//&& 与操作:同真为真,有一个假结果为假
//|| 或操作:同假为假,有一个真为真
//! 非操作
System.out.println("12 > 5 && true: "+(12 > 5 && true));
System.out.println("true && true && false && true: " + (true && true && false && true));
//&& 运算的短路性:如果能确定结果,就无须继续走下去,如上面的与操作
}
}
//Output:
12 > 5 && true: true
true && true && false && true: false
按位操作符
按位操作符操作的是数据的二进制形式的每一位,位运算主要是对底层进行操作,平时用的也少,所以比较陌生。
- 与,或和异或
技 巧:
- & 与运算: 遇 0 则为 0, 全1 则为 1
- | 或运算: 遇 1 则为 1, 全 0 则为 0
- ^ 异或运算: 相同则为 1 ,不同 则为 0
Tips: &、|和&&、||的区别是,逻辑与、或操作只能操作布尔型,而按位的与、或可以操作布尔型和数字型。
public class Main{
public static void main(String[] args){
int i = 12;
int j = 15;
int m = -12;
int n = -15;
System.out.println(Integer.toBinaryString(i));
System.out.println(Integer.toBinaryString(j));
System.out.println(Integer.toBinaryString(m));
System.out.println(Integer.toBinaryString(n));
//与运算
System.out.println("i & j = "+Integer.toBinaryString(i & j)
+ "\t" + (i & j));
System.out.println("m & n = "+Integer.toBinaryString(m & n)
+ "\t" + (m & n));
//或运算
System.out.println("i | j = "+Integer.toBinaryString(i | j)
+ "\t" + (i | j));
System.out.println("m | n = "+Integer.toBinaryString(m | n)
+ "\t" + (m | n));
//异或运算
System.out.println("i ^ j = "+Integer.toBinaryString(i ^ j)
+ "\t" + (i ^ j));
System.out.println("m ^ n = "+Integer.toBinaryString(m ^ n)
+ "\t" + (m ^ n));
}
}
//Output:
1100
1111
11111111111111111111111111110100
11111111111111111111111111110001
i & j = 1100 12
m & n = 11111111111111111111111111110000 -16
i | j = 1111 15
m | n = 11111111111111111111111111110101 -11
i ^ j = 11 3
m ^ n = 101 5
Tips: toBinaryString
方法可以将一个Integer类型的数字转换为无符号二进制字符串。(具体转换可以看看Java API中的介绍)
拓展:Java中进制输出
在Java中二进制正数,只显示从左到右、非零位开始的剩余部分;负数使用的二进制补码形式。
- 非运算
技 巧:
- 结果为:正整数加一,变为负数(二进制形式为按位取反结果为负数补码)
- 结果为:负整数加一,变为整数(二进制形式为按位取反结果为正数原码)
- 0 按位取反结果为 -1
public class Main{
public static void main(String[] args){
int i = 20;
System.out.println(Integer.toBinaryString(i));
int j = ~i;
System.out.println(j);
System.out.println(Integer.toBinaryString(j));
int m = -12;
int n = ~m;
System.out.println(Integer.toBinaryString(m));
System.out.println(n);
System.out.println(Integer.toBinaryString(n));
}
}
//Output:
10100
-21
11111111111111111111111111101011
11111111111111111111111111110100
11
1011
Tips: 非运算可以和赋值运算符复合使用,效果通复合的算术运算符。
拓展:二进制原码、补码、反码计算,如何求得Java中取反获得的十进制负数
移位操作符
移位操作符同样属于位操作符,但是移位操作符只能操作整数,箭头指向移动的方向。
- 右移和左移
技 巧:
- 左移 <<: 操作数的每一位都向左移,在地位补零
- 右移 >>: 正数右移高位补零,负数右移高位插入1(符号扩展)
public class Main{
public static void main(String[] args){
int i = 20;
int j = -20;
System.out.println(Integer.toBinaryString(i));
//左移
System.out.println(Integer.toBinaryString(i<<1) + "\t" + (i<<1));
System.out.println(Integer.toBinaryString(j<<1) + "\t" + (j<<1));
//右移
System.out.println(Integer.toBinaryString(i>>1) + "\t" + (i>>1));
System.out.println(Integer.toBinaryString(j>>1) + "\t" + (j>>1));
}
}
//Output:
10100
101000 40
11111111111111111111111111011000 -40
1010 10
11111111111111111111111111110110 -10
- 无符号右移
Java中新增的,在C/C++中没有的操作符。
技 巧:
无符号右移 >>>:“零扩展”,无论是整数还是负数,都是在高位补0
public class Assignment{
public static void main(String[] args){
int i = 20;
int j = -20;
//无符号右移
System.out.println(Integer.toBinaryString(i));
System.out.println(Integer.toBinaryString(i>>>1) + "\t" + (i>>>1));
System.out.println(Integer.toBinaryString(j));
System.out.println(Integer.toBinaryString(j>>>1) + "\t" + (j>>>1));
}
}
//Output:
10100
1010 10
11111111111111111111111111101100
1111111111111111111111111110110 2147483638
结语
- 一元操作符可以改变操作数自身的值:如算术运算符的 正号
+
负号-
自增++
自减--
;按位操作符的 非运算~
。 - 一个表达式的结果类型由这个表达式中的最大范围的类型决定。