运算符

靠近表顶部的运算符,其优先级最高。具有较高优先级的运算符在相对较低的优先级的运算符之前被评估。在同一行上的运算符具有相同的优先级。当在相同的表达式中出现相同优先级的运算符时,必须首先对该规则进行评估。除了赋值运算符外,所有二进制运算符进行评估从左到右,赋值操作符是从右到左。

运算符优先级表:

运算符 优先级
后缀(postfix) expr++ expr--
一元运算(unary) ++expr --expr +expr -expr ~ !
乘法(multiplicative) * / %
加法(additive) + -
移位运算(shift) << >> >>>
关系(relational) < > <= >= instanceof
相等(equality) == !=
与运算(bitwise AND) &
异或运算(bitwise exclusive OR) ^
或运算(bitwise inclusive OR) ` `
逻辑与运算(logical AND) &&
逻辑或运算(logical OR) ` `
三元运算(ternary) ? :
赋值运算(assignment) `= += -= *= /= %= &= ^= = <<= >>= >>>=`

赋值运算符

赋值运算符是最常用和最简单的运算符就是=,如下:

  1. int cadence = 0;
  2. int speed = 0;
  3. int gear = 1;

该运算符也用于对象的引用关联。

算术运算符

算术运算符包括:

运算符 | 描述
|:——:| ——|
|+ | 加 (也用于 String 的连接)|
|- | 减|
|* | 乘|
|/ | 除|
|% | 取余|

ArithmeticDemo 的例子

  1. class ArithmeticDemo {
  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args) {
  6. int result = 1 + 2;
  7. // result is now 3
  8. System.out.println("1 + 2 = " + result);
  9. int original_result = result;
  10. result = result - 1;
  11. // result is now 2
  12. System.out.println(original_result + " - 1 = " + result);
  13. original_result = result;
  14. result = result * 2;
  15. // result is now 4
  16. System.out.println(original_result + " * 2 = " + result);
  17. original_result = result;
  18. result = result / 2;
  19. // result is now 2
  20. System.out.println(original_result + " / 2 = " + result);
  21. original_result = result;
  22. result = result + 8;
  23. // result is now 10
  24. System.out.println(original_result + " + 8 = " + result);
  25. original_result = result;
  26. result = result % 7;
  27. // result is now 3
  28. System.out.println(original_result + " % 7 = " + result);
  29. }
  30. }

输出为:

  1. 1 + 2 = 3
  2. 3 - 1 = 2
  3. 2 * 2 = 4
  4. 4 / 2 = 2
  5. 2 + 8 = 10
  6. 10 % 7 = 3

+ 用于字符串连接的例子 ConcatDemo :

  1. class ConcatDemo {
  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args) {
  6. String firstString = "This is";
  7. String secondString = " a concatenated string.";
  8. String thirdString = firstString+secondString;
  9. System.out.println(thirdString);
  10. }
  11. }

一元操作

一元运算符只需要一个操作数。

运算符 | 描述
|:——:| ——|
|+ | 加运算;指正值|
|- | 减运算符;表达成负值|
|++ | 递增运算符;递增值1|
|— | 递减运算符;递减值1|
|!| 逻辑补运算;反转一个布尔值|

下面是 UnaryDemo 的示例:

  1. class UnaryDemo {
  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args) {
  6. int result = +1;
  7. // result is now 1
  8. System.out.println(result);
  9. result--;
  10. // result is now 0
  11. System.out.println(result);
  12. result++;
  13. // result is now 1
  14. System.out.println(result);
  15. result = -result;
  16. // result is now -1
  17. System.out.println(result);
  18. boolean success = false;
  19. // false
  20. System.out.println(success);
  21. // true
  22. System.out.println(!success);
  23. }
  24. }

递增/递减运算符可以之前(前缀)或(后缀)操作数后应用。该代码result++;++result; 两个的 result 都被加一。唯一的区别是,该前缀版本++result;增递增了,而后缀版本result++;的计算结果为原始值。下面是 PrePostDemo 的示例,说明了两者的区别:

  1. class PrePostDemo {
  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args) {
  6. int i = 3;
  7. i++;
  8. // prints 4
  9. System.out.println(i);
  10. ++i;
  11. // prints 5
  12. System.out.println(i);
  13. // prints 6
  14. System.out.println(++i);
  15. // prints 6
  16. System.out.println(i++);
  17. // prints 7
  18. System.out.println(i);
  19. }
  20. }

等价和关系运算符

等价和关系运算符包括

运算符 | 描述
|:——:| ——|
|== | 相等(equal to)|
|!= | 不相等(not equal to)|
|> | 大于(greater than)|
|>= | 大于等于(greater than or equal to)|
|< | 小于(less than)|
|<= | 小于等于(less than or equal to)|

ComparisonDemo 对比的例子:

  1. class ComparisonDemo {
  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args) {
  6. int value1 = 1;
  7. int value2 = 2;
  8. if (value1 == value2)
  9. System.out.println("value1 == value2");
  10. if (value1 != value2)
  11. System.out.println("value1 != value2");
  12. if (value1 > value2)
  13. System.out.println("value1 > value2");
  14. if (value1 < value2)
  15. System.out.println("value1 < value2");
  16. if (value1 <= value2)
  17. System.out.println("value1 <= value2");
  18. }
  19. }

输出为:

  1. value1 != value2
  2. value1 < value2
  3. value1 <= value2

条件运算符

条件运算符包括:

运算符 | 描述
|:——:| ——|
| && | 条件与(Conditional-AND)|
| || | 条件或(Conditional-OR)|
| ?: | 三元运算符(ternary operator)|

条件与、条件或的运算符例子 ConditionalDemo1:

  1. class ConditionalDemo1 {
  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args) {
  6. int value1 = 1;
  7. int value2 = 2;
  8. if ((value1 == 1) && (value2 == 2))
  9. System.out.println("value1 is 1 AND value2 is 2");
  10. if ((value1 == 1) || (value2 == 1))
  11. System.out.println("value1 is 1 OR value2 is 1");
  12. }
  13. }

输出:

value1 is 1 AND value2 is 2
value1 is 1 OR value2 is 1

下面是一个三元运算符的例子,类似与 if-then-else 语句,见 ConditionalDemo2 :

  1. class ConditionalDemo2 {
  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args) {
  6. int value1 = 1;
  7. int value2 = 2;
  8. int result;
  9. boolean someCondition = true;
  10. result = someCondition ? value1 : value2;
  11. System.out.println(result);
  12. }
  13. }

instanceof 运算符

instanceof 用于匹配判断对象的类型。可以用它来测试对象是否是类的一个实例,子类的实例,或者是实现了一个特定接口的类的实例。见例子 InstanceofDemo,父类是 Parent ,接口是 MyInterface ,子类是 Child 继承了父类并实现了接口。

  1. class InstanceofDemo {
  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args) {
  6. // Must qualify the allocation with an enclosing instance of type InstanceofDemo
  7. Parent obj1 = new InstanceofDemo().new Parent();
  8. Parent obj2 = new InstanceofDemo().new Child();
  9. System.out.println("obj1 instanceof Parent: "
  10. + (obj1 instanceof Parent));
  11. System.out.println("obj1 instanceof Child: "
  12. + (obj1 instanceof Child));
  13. System.out.println("obj1 instanceof MyInterface: "
  14. + (obj1 instanceof MyInterface));
  15. System.out.println("obj2 instanceof Parent: "
  16. + (obj2 instanceof Parent));
  17. System.out.println("obj2 instanceof Child: "
  18. + (obj2 instanceof Child));
  19. System.out.println("obj2 instanceof MyInterface: "
  20. + (obj2 instanceof MyInterface));
  21. }
  22. class Parent {}
  23. class Child extends Parent implements MyInterface {}
  24. interface MyInterface {}
  25. }

输出为:

  1. obj1 instanceof Parent: true
  2. obj1 instanceof Child: false
  3. obj1 instanceof MyInterface: false
  4. obj2 instanceof Parent: true
  5. obj2 instanceof Child: true
  6. obj2 instanceof MyInterface: true

注:null 不是任何类的实例

位运算和位移运算符

位运算和位移运算符适用于整型。

位运算符

运算符 | 描述
|:——:| ——|
| & | 与|
| | | 或|
| ^ | 异或|
| ~ | 非(把0变成1,把1变成0)|

BitDemo 例子:

  1. class BitDemo {
  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args) {
  6. int bitmask = 0x000F;
  7. int val = 0x2222;
  8. // prints "2"
  9. System.out.println(val & bitmask);
  10. }
  11. }

位移运算符

首先我们先阐述一下符号位的概念:

  • 符号位:是数的最后一位,不用来计算的;
  • 当符号位为0时,值为正数;当符号位为1时,值为负数;
  • 无符号位时为正数,有符号位时为正数或者负数;

运算符 | 描述
|:——:| ——|
| << | 左移|
| >> | 右移|
| >>> | 右移(补零)|

左移(<<) 运算形式:值 << 位数

右移(>>) 运算形式:值 >> 位数

移动后,左移、右移都会保留符号位!

右移(补零),移动后,不保留符号位,永远为正数,因为其符号位总是被补零;

源码

本章例子的源码,可以在 com.waylau.essentialjava.operator 包下找到。