语言基础 - 运算符
靠近表顶部的运算符,其优先级最高。具有较高优先级的运算符在相对较低的优先级的运算符之前被评估。在同一行上的运算符具有相同的优先级。当在相同的表达式中出现相同优先级的运算符时,必须首先对该规则进行评估。除了赋值运算符外,所有二进制运算符进行评估从左到右,赋值操作符是从右到左。
运算符优先级表:
运算符 | 优先级 | ||
---|---|---|---|
后缀(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) | `= += -= *= /= %= &= ^= | = <<= >>= >>>=` |
赋值运算符
赋值运算符是最常用和最简单的运算符就是=
,如下:
int cadence = 0;
int speed = 0;
int gear = 1;
该运算符也用于对象的引用关联。
算术运算符
算术运算符包括:
运算符 | 描述
|:——:| ——|
|+ | 加 (也用于 String 的连接)|
|- | 减|
|* | 乘|
|/ | 除|
|% | 取余|
ArithmeticDemo 的例子
class ArithmeticDemo {
/**
* @param args
*/
public static void main(String[] args) {
int result = 1 + 2;
// result is now 3
System.out.println("1 + 2 = " + result);
int original_result = result;
result = result - 1;
// result is now 2
System.out.println(original_result + " - 1 = " + result);
original_result = result;
result = result * 2;
// result is now 4
System.out.println(original_result + " * 2 = " + result);
original_result = result;
result = result / 2;
// result is now 2
System.out.println(original_result + " / 2 = " + result);
original_result = result;
result = result + 8;
// result is now 10
System.out.println(original_result + " + 8 = " + result);
original_result = result;
result = result % 7;
// result is now 3
System.out.println(original_result + " % 7 = " + result);
}
}
输出为:
1 + 2 = 3
3 - 1 = 2
2 * 2 = 4
4 / 2 = 2
2 + 8 = 10
10 % 7 = 3
+
用于字符串连接的例子 ConcatDemo :
class ConcatDemo {
/**
* @param args
*/
public static void main(String[] args) {
String firstString = "This is";
String secondString = " a concatenated string.";
String thirdString = firstString+secondString;
System.out.println(thirdString);
}
}
一元操作
一元运算符只需要一个操作数。
运算符 | 描述
|:——:| ——|
|+ | 加运算;指正值|
|- | 减运算符;表达成负值|
|++ | 递增运算符;递增值1|
|— | 递减运算符;递减值1|
|!| 逻辑补运算;反转一个布尔值|
下面是 UnaryDemo 的示例:
class UnaryDemo {
/**
* @param args
*/
public static void main(String[] args) {
int result = +1;
// result is now 1
System.out.println(result);
result--;
// result is now 0
System.out.println(result);
result++;
// result is now 1
System.out.println(result);
result = -result;
// result is now -1
System.out.println(result);
boolean success = false;
// false
System.out.println(success);
// true
System.out.println(!success);
}
}
递增/递减运算符可以之前(前缀)或(后缀)操作数后应用。该代码result++;
和 ++result;
两个的 result 都被加一。唯一的区别是,该前缀版本++result;
增递增了,而后缀版本result++;
的计算结果为原始值。下面是 PrePostDemo 的示例,说明了两者的区别:
class PrePostDemo {
/**
* @param args
*/
public static void main(String[] args) {
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
等价和关系运算符
等价和关系运算符包括
运算符 | 描述
|:——:| ——|
|== | 相等(equal to)|
|!= | 不相等(not equal to)|
|> | 大于(greater than)|
|>= | 大于等于(greater than or equal to)|
|< | 小于(less than)|
|<= | 小于等于(less than or equal to)|
ComparisonDemo 对比的例子:
class ComparisonDemo {
/**
* @param args
*/
public static void main(String[] args) {
int value1 = 1;
int value2 = 2;
if (value1 == value2)
System.out.println("value1 == value2");
if (value1 != value2)
System.out.println("value1 != value2");
if (value1 > value2)
System.out.println("value1 > value2");
if (value1 < value2)
System.out.println("value1 < value2");
if (value1 <= value2)
System.out.println("value1 <= value2");
}
}
输出为:
value1 != value2
value1 < value2
value1 <= value2
条件运算符
条件运算符包括:
运算符 | 描述
|:——:| ——|
| &&
| 条件与(Conditional-AND)|
| ||
| 条件或(Conditional-OR)|
| ?:
| 三元运算符(ternary operator)|
条件与、条件或的运算符例子 ConditionalDemo1:
class ConditionalDemo1 {
/**
* @param args
*/
public static void main(String[] args) {
int value1 = 1;
int value2 = 2;
if ((value1 == 1) && (value2 == 2))
System.out.println("value1 is 1 AND value2 is 2");
if ((value1 == 1) || (value2 == 1))
System.out.println("value1 is 1 OR value2 is 1");
}
}
输出:
value1 is 1 AND value2 is 2
value1 is 1 OR value2 is 1
下面是一个三元运算符的例子,类似与 if-then-else 语句,见 ConditionalDemo2 :
class ConditionalDemo2 {
/**
* @param args
*/
public static void main(String[] args) {
int value1 = 1;
int value2 = 2;
int result;
boolean someCondition = true;
result = someCondition ? value1 : value2;
System.out.println(result);
}
}
instanceof 运算符
instanceof 用于匹配判断对象的类型。可以用它来测试对象是否是类的一个实例,子类的实例,或者是实现了一个特定接口的类的实例。见例子 InstanceofDemo,父类是 Parent ,接口是 MyInterface ,子类是 Child 继承了父类并实现了接口。
class InstanceofDemo {
/**
* @param args
*/
public static void main(String[] args) {
// Must qualify the allocation with an enclosing instance of type InstanceofDemo
Parent obj1 = new InstanceofDemo().new Parent();
Parent obj2 = new InstanceofDemo().new Child();
System.out.println("obj1 instanceof Parent: "
+ (obj1 instanceof Parent));
System.out.println("obj1 instanceof Child: "
+ (obj1 instanceof Child));
System.out.println("obj1 instanceof MyInterface: "
+ (obj1 instanceof MyInterface));
System.out.println("obj2 instanceof Parent: "
+ (obj2 instanceof Parent));
System.out.println("obj2 instanceof Child: "
+ (obj2 instanceof Child));
System.out.println("obj2 instanceof MyInterface: "
+ (obj2 instanceof MyInterface));
}
class Parent {}
class Child extends Parent implements MyInterface {}
interface MyInterface {}
}
输出为:
obj1 instanceof Parent: true
obj1 instanceof Child: false
obj1 instanceof MyInterface: false
obj2 instanceof Parent: true
obj2 instanceof Child: true
obj2 instanceof MyInterface: true
注:null 不是任何类的实例
位运算和位移运算符
位运算和位移运算符适用于整型。
位运算符
运算符 | 描述
|:——:| ——|
| &
| 与|
| |
| 或|
| ^
| 异或|
| ~
| 非(把0变成1,把1变成0)|
BitDemo 例子:
class BitDemo {
/**
* @param args
*/
public static void main(String[] args) {
int bitmask = 0x000F;
int val = 0x2222;
// prints "2"
System.out.println(val & bitmask);
}
}
位移运算符
首先我们先阐述一下符号位的概念:
- 符号位:是数的最后一位,不用来计算的;
- 当符号位为0时,值为正数;当符号位为1时,值为负数;
- 无符号位时为正数,有符号位时为正数或者负数;
运算符 | 描述
|:——:| ——|
| <<
| 左移|
| >>
| 右移|
| >>>
| 右移(补零)|
左移(<<) 运算形式:值 << 位数
右移(>>) 运算形式:值 >> 位数
移动后,左移、右移都会保留符号位!
右移(补零),移动后,不保留符号位,永远为正数,因为其符号位总是被补零;
源码
本章例子的源码,可以在 com.waylau.essentialjava.operator
包下找到。