第三章《控制程序流程》
Java运算符
### 赋值
class Number {
int i;
}
public class Assignment {
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
n1.i = 9;
n2.i = 47;
System.out.println("1: n1.i: " + n1.i + ", n2.i: " + n2.i);
n1 = n2;
System.out.println("2: n1.i: " + n1.i + ", n2.i: " + n2.i);
n1.i = 27;
System.out.println("3: n1.i: " + n1.i + ", n2.i: " + n2.i);
}
}
/**
* out
* 1: n1.i: 9, n2.i: 47
* 2: n1.i: 47, n2.i: 47
* 3: n1.i: 27, n2.i: 27
*/
- 开始的时候第三个输出很迷惑,后面知道了:
n1.i = 27;
只改变了一个对象,两个句柄指向同一个对象,故打印的时候都是27
算术运算符
- 整数除法会直接砍掉小数,而不是进位。
+,—
的优先级比*,/
的高,+
(正号),-
(负号)例:x = a * -b;
- (如++A或–A),会先执行运算,再生成值。而对于后递增和后递减(如A++或A–),会先生成值,再执行运算
public class AutoInc {
public static void main(String[] args) {
int i = 1;
prt("i : " + i);
prt("++i : " + ++i); // Pre-increment
prt("i++ : " + i++); // Post-increment
prt("i : " + i);
prt("--i : " + --i); // Pre-decrement
prt("i-- : " + i--); // Post-decrement
prt("i : " + i);
}
static void prt(String s) {
System.out.println(s);
}
}
/**
* out
* i : 1
* ++i : 2
* i++ : 2
* i : 3
* --i : 2
* i-- : 2
* i : 1
*/
关系运算符
- 关系运算符包括小于(<)、大于(>)、小于或等于(<=)、大于或等于(>=)、等于(==)以及不等于(!=)。等于和不等于适用于所有内建的数据类型,但其他比较不适用于boolean类型。
- ==和!=比较的正好就是对象句柄
public class Equivalence {
public static void main(String[] args) {
Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1 == n2);
System.out.println(n1 != n2);
System.out.println(n1.equals(n2));
}
}
/**
* out:
* false
* true
* true
*/
Integer equals源码
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
- equals()的默认行为是比较句柄,大多数Java类库都实现了equals(),所以它实际比较的是对象的内容,而非它们的句柄。
逻辑运算符
- 逻辑运算符AND(&&)、OR(||)以及NOT(!)能生成一个布尔值(true或false)——以自变量的逻辑关系为基础,注意若在预计为String值的地方使用,布尔值会自动转换成适当的文本形式
-操作逻辑运算符时,我们会遇到一种名为“短路”的情况。这意味着只有明确得出整个表达式真或假的结论,才会对表达式进行逻辑求值。因此,一个逻辑表达式的所有部分都有可能不进行求值
按位运算
- 若两个输入位都是1,则按位AND运算符(&)在输出位里生成一个1;否则生成0。若两个输入位里至少有一个是1,则按位OR运算符(|)在输出位里生成一个1;只有在两个输入位都是0的情况下,它才会生成一个0。若两个输入位的某一个是1,但不全都是1,那么按位XOR(^,异或)在输出位里生成一个1。按位NOT(~,也叫作“非”运算符)属于一元运算符;它只对一个自变量进行操作(其他所有运算符都是二元运算符)。按位NOT生成与输入位的相反的值——若输入0,则输出1;输入1,则输出0。
- 按位运算符可与等号(=)联合使用,以便合并运算及赋值:&=,|=和^=都是合法的(由于~是一元运算符,所以不可与=联合使用)。
移位运算
- 移位运算符面向的运算对象也是二进制的“位”。可单独用它们处理整数类型(主类型的一种)。左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补0)。“有符号”右移位运算符(>>)则将运算符左边的运算对象向右移动运算符右侧指定的位数。“有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。Java也添加了一种“无符号”右移位运算符(>>>),它使用了“零扩展”:无论正负,都在高位插入0。这一运算符是C或C++没有的。
- 若对char,byte或者short进行移位处理,那么在移位进行之前,它们会自动转换成一个int
- 移位可与等号(<<=或>>=或>>>=)组合使用。此时,运算符左边的值会移动由右边的值指定的位数,再将得到的结果赋回左边的值。
三元运算符
-
布尔表达式 ? 值0:值1
若“布尔表达式”的结果为true,就计算“值0”,而且它的结果成为最终由运算符产生的值。但若“布尔表达式”的结果为false,计算的就是“值1”,而且它的结果成为最终由运算符产生的值。
运算符类型 | 中文 | 运算符 |
---|---|---|
Unary | 一元运算符 | + - ++ – [[ rest...]] |
Arithmetic (and shift) | 算术元算和移位 | * / % + - << >> |
Relational | 关系运算 | > < >= <= == != |
Logical (and bitwise) | 逻辑运算和按位运算 | ** && |
Conditional (ternary) | 三元 | A > B ? X : Y |
Assignment | = (and compound assignment like *=) |
执行控制
-
简单的一个continue会退回最内层循环的开头(顶部),并继续执行。
-
带有标签的continue会到达标签的位置,并重新进入紧接在那个标签后面的循环。
-
break会中断当前循环,并移离当前标签的末尾。
-
带标签的break会中断当前循环,并移离由那个标签指示的循环的末尾。
Math.random()
的范围是[0,1)
成员初始化
初始化顺序
在一个类里,初始化的顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间,那些变量仍会在调用任何方法之前得到初始化——甚至在构建器调用之前