Operators
5 operators: Arithmetic
(+,-,*,/), Assignment
(=,+=,*=), Relational
(>,<,=), Logical
(&,&&,|,||), Byte Manipulation
order of operations 运算符优先级
❗ 速记 PUMA is a REBL TA.
Operator | Symbols |
---|---|
Post-Unary | expr++ , expr-- |
Pre-Unary | ++ expr, -- expr |
Brackets | ( ) |
Other Unary | + expr, - expr, ! expr |
Multiplicative | * , / ,% |
Additive | + , - |
Relational | < , > , <= ,>= , instanceof |
Equality | == , != |
Bitwise | |
Logical | & , ^ , ` |
Logical short-circuit | && , ` |
Ternary | expr ? expr : expr |
Assignment | = , += , -+ , *= , /= , %= |
Arithmetic promotion
在基础类型的四则运算中,编译器会自动将类型提升到运算表达式的最高类型,默认类型是int
类型
byte xByte = 3; byte yByte = 4; byte zByte = 0;
// 下面语句会编译错误,表达式结果被提升到默认的int,而zByte却是casting,因此必须casting
zByte = xByte + yByte;
byte xByte = 3; double yDouble = 4.0; byte zByte = 0;
// 下面语句会编译错误,表达式的最高类型都是byte,
// 所以表达式结果被提升到默认的int,而zByte是byte类型,所以错误
zByte = (byte)xByte + (byte)yDouble;
// 下面语句编译错误,因为被提升到最高的类型double
zByte = xByte + yDouble;
// 正确的做法是对整个表达式的结果做casting -> int类型narrow到byte类型
zByte = (byte)( xByte + yDouble );
Pre- and Post-Unary operators
Post-Unary优先级高于pre-unary, 赋值表达式的计算从左至右
pre-unary在表达式前先将variable的值自增/减,post-unary在表达式结束后将variable自增/减
int xInt = 4; int yInt = 7; int zInt = 3;
int result = ++xInt + yInt + --zInt; // 14
// 5(xInt=5) 7 2(zInt=2)
int result = ++xInt + xInt + ++xInt; //16
// 5(XInt=5) 5 6(xInt=6)
int result = ++xInt + ++xInt + xInt; // 17
// 5(XInt=5) 6(xInt=6) 6
int result = xInt++ + xInt + xInt++; // 14
// 4(xInt=4) 5 5(xInt=5)
Assignment Operators
assignment operators: +=
, -+
, *=
, /=
, %=
⚠️ assignment operator itself can also be used an operation
❗ 经典使用案例:在if等条件语句中使用assignment operator,错误的使用可能会带来意想不到的错误
int x = 5; int y = 3; int z = x + y;
z = 5 + ( y = x + y ); // z = 13, y = 8
// 经典例子
boolean flag = false; z = 0;
if( flag = true ) { // = 是赋值符号,此处flag被赋值为true,因此进入if语句块
z = 5;
}else{
z = 3;
}
// z = 5!!!
compound assignment operators: +=
, *=
, -=
, /=
, %=
❗ arithmetic promotion doesn't occur in compound assignments which casts the results automatically
⚠️ compound assignments widen or cast the result to the assigned type
xByte = (byte)( xByte + yDouble )// arithmetic promotion leads to the compile error
byte xByte = 5; double yDouble = 3.0;
xByte = xByte + yDouble;
// xByte = (byte)( xByte + yDouble ); 才是正确的
// compound assignment会自动对结果做casting, 因此无编译错误
xByte += yDouble; // 等同于xByte = (byte)( xByte + yDouble )
float afloat = 5.0f; double yDouble = 3.0; long along = 10L; short ashort = 3; byte abyte = 0;
abyte += yDouble + afloat * along % ashort; // 10
comparison/relational operators
comparison/relational operators: <
, >
, <=
,>=
, instanceof
, ==
, !=
⚠️
<
,>
,<=
,>=
只能用于numerical types, 用于其他类型的时候会有compile error
==
,!=
只能用于primitive types, object references, Boolean
instanceof
只能用于object instances
boolean result = false; int aint = 3; long along = 4L;
result = aint != along; // true
class ClassA{}; class ClassB extends ClassA {};
ClassA instanceA = new ClassA(); ClassB instanceB = new ClassB();
boolean result = ( instanceA instanceof ClassA ); // true
result = ( instanceB instanceof ClassA ); // true
result = ( instanceA instanceof ClassB ); // false
comparison operators themselves can be operands 比较表达式本身也可以作为操作数
int xInt = 3; long yLong = 3L; float zFloat = 3.1f;
boolean result = ( ( zFloat >= yLong ) == ( xInt <= zFloat ) );
logical operators
logical operators: &
, ^
, |
, &&
, ||
, !
&
: both sides must be true, both sides are tested
&&
: both sides must be true, short-circuit if the left is false
|
: at least one side must be true, both sides are tested
||
: at least one side must be true, short-circuit if the left is true
^
: one side must be false, and the other side true 两边逻辑值不同时才返回true
!
: reverses the boolean
order of operations
赋值语句总是从左至右计算各表达式,在一个表达式里根据相邻的两个操作符的优先级进行先后计算
⚠️ 用后缀表达式的思想来考虑整个计算过程,就可以非常清晰正确的计算出结果了
int x = 3; int y = 4; int z = 0;
// ++ 和 + 比较,++优先级高,先计算x++
// + 和 + 比较,等同优先级,先左后右,所以y = 4
// + 和 -- 比较, --优先级高,先计算--y
z = x++ + y + --y + x; // 14
// 3(x=4) 4(y=4) 3(y=3) 4
z = x + y + --y + x++; // 13
// 3 4 3(y=3) 3(x=4)
⚠️ 经典例子 - -
的优先级高于>
, >
高于 ? :
int x = 3; int y = 6; int z = 2;
z *= y / x - y - x > y ? 4 : 2; // 4
// 相当于
z *= ( (y/x - y - x) > y ) ? 4 : 2;
⚠️ 括号的优先级仅仅低于Pre- and Post-unary
int x = 3, y = 4;
int z = --x * x + y + 8; // 16
// --优先于(), 因此先计算--x
int z = --x * ( x + y + 8 ); // 28