本章主要为 Java 操作符与控制执行流程的相关笔记。
赋值
对基本数据类型的赋值是简单的。基本类型存储了实际的数值,而并非指向一个对象的引用,所以在赋值时,是直接将一个地方的内容复制到另一个地方。例如:对基本数据类型使用 a = b
,那么修改 a
的内容,b
不会受到影响。
在对象赋值时,由于是对对象的引用进行操作,所以实际上是将引用复制到另一个地方。例如:对对象使用 c = d
,那么 c
和 d
都指向原本只有 d
指向的那个对象。另外,将一个对象传递给方法时,大多数情况下,传递的也是引用。
算术操作符
一元减号和一元加号,都能将较小类型的操作数提升为 int
,例如:1
2short a = 10;
short b = +a; // Incompatible types. Required: short , Found: int
自动递增和递减
对于前缀递增和前缀递减(如 ++a
或 --a
),会先执行运算,再生成值。而对于后缀递增和后缀递减(如 a++
或 a--
),会先生成值,再执行运算。例如:1
2
3int a = 10;
System.out.println(a++); // 10
System.out.println(++a); // 12
对象的等价性
对于基本类型来说,使用 ==
和 !=
即可。对于对象来说, ==
仅仅只是比较对象的引用是否相同。如果想比较两个对象的实际内容,应该使用 equals()
方法。另外,对于自定义的类,需要在类中覆盖 equals()
方法后,才能进行正确的比较。
逻辑短路
当使用逻辑操作符时,我们会遇到一种短路现象,即一旦能够明确无误地确定整个表达式的值,就不再计算表达式余下部分了。
直接常量
位置 | 符号 | 含义 |
---|---|---|
后缀 | L(l) | long |
后缀 | F(f) | float |
后缀 | D(d) | double |
前缀 | 0X(0x) | 十六进制 |
前缀 | 0 | 八进制 |
通过使用 Integer
和 Long
类的静态方法 toBinaryString()
可以很容易得到对应的二进制数。
在 Java 里,e 代表 10 的幂次,并且默认是 double
类型的。例如:1e2 = 100.0
按位操作符
& | | | ^ |
---|---|---|
0 & 0 = 0 | 0 | 0 = 0 | 0 ^ 0 = 0 |
0 & 1 = 0 | 0 | 1 = 1 | 0 ^ 1 = 1 |
1 & 0 = 0 | 1 | 0 = 1 | 1 ^ 0 = 1 |
1 & 1 = 1 | 1 | 1 = 1 | 1 ^ 1 = 0 |
按位非(~),取反操作符,属于一元操作符,对操作数按位取反。1
2int i = 0;
System.out.println(~i); // -1
按位操作符可与等号(=)联合使用,例如:&=
,|=
,^=
都是合法的(由于 ~
是一元操作符,所以不可与 =
联合使用)。按位操作符还可以对布尔类型进行操作( ~
除外),同时不会出现短路现象。
移位操作符
移位操作符只可用来处理整数类型。
左移位操作符(<<) | 有符号右移位操作符(>>) | 无符号右移位操作符(>>>) |
---|---|---|
低位补 0 | 符号位正,高位补 0;符号为负,高位补 1 | 高位补 0 |
对较小的数据类型进行移位处理,在移位之前会自动转换为 int
类型,并且右操作数只有低 5 位才有用(因为 int
为 32 位,为了避免无意义的移位)。同理,对 long
进行操作,右操作数只有低 6 位才有用。1
2
3
4
5
6
7
8
9short i = 2;
i = i << 2; // Incompatible types. Required: short. Found: int.
int i = 16;
System.out.println(i + " : " + Integer.toBinaryString(i)); // 16 : 10000
System.out.println((i << 1) + " : " + Integer.toBinaryString(i << 1)); // 32 : 100000
System.out.println((i << 31) + " : " + Integer.toBinaryString(i << 31)); // 0 : 0
System.out.println((i << 33) + " : " + Integer.toBinaryString(i << 33)); // 32 : 100000
三元操作符
相比 if-else
显得更加简练:1
2int n = 10;
System.out.println(n < 100 ? n : 100); // 10
forEach 语法
对于数组和容器,forEach
将自动产生每一项:1
2
3
4int[] n = {1, 2, 3, 4, 5};
for (int x : n) {
System.out.println(x);
}
标签
标签必须在迭代语句之前声明,主要用于多重循环:
- 一般的
continue
会退回最内层循环的开头,并继续执行 - 带标签的
continue
会达到标签的位置,并重新进入紧接在那个标签后面的循环 - 一般的
break
会中断并跳出当前循环 - 带标签的
break
会中断并跳出标签所指的循环1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31outer:
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
System.out.print("[" + i + " " + j + "] "); // [0 0] [0 1] [1 0] [1 1]
continue;
}
}
outer:
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
System.out.print("[" + i + " " + j + "] "); // [0 0] [1 0]
continue outer;
}
}
outer:
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
System.out.print("[" + i + " " + j + "] "); // [0 0] [1 0]
break;
}
}
outer:
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
System.out.print("[" + i + " " + j + "] "); // [0 0]
break outer;
}
}