1 作用
接受参数并生成新值。与普通方法调用殊途同归。所有运算符都能根据自己的运算对象生成一个值。
1.1 副作用(Side Effect)
可改变运算对象的值。
1.2 最常见用途
修改自己的运算对象,从而产生副作用。注意生成的值亦可由没有副作用的运算符生成。
几乎所有运算符都只能操作基本类型(Primitives)。
唯一例外是 =、== 和 !=,它们能操作所有对象(这也是令人混淆的一个地方)。
此外,String 类支持 + 和 +=。编译器会将 + 连接的非字符串尝试转换为字符串
2 优先级
2.1 作用
决定了存在多个运算符时一个表达式各部分的运算顺序。程序员经常习惯性忘记优先级规则,所以要用括号明确规定运算顺序。
2.2 赋值运算符 (=)
2.2.1 作用
获取右值并赋给左值。右值可以是任何常量、变量或者可产生一个返回值的表达式。左值必须是一个明确的、已命名的变量。即要有一个物理空间存放右值。
基本类型的赋值很简单。因为基本类型持有的是实际的值而非一个对象的引用。只是将内容从一个地方复制到另一个地方。
赋值对象时,实际上是把引用从一个地方复制到另一个地方。这种现象通常称为别名(aliasing),这是 Java 处理对象的一种基本方式。这种场景经常出现在方法参数的传递。
2.3 算术运算符
- 整数除法会直接截断,而非进位
- +=,-= 与 C++ 相同的简写形式同时进行运算和赋值操作,由运算符后跟等号表示,并且与语言中的所有运算符一致(只要有意义)
一元减号可以得到数据的负值。一元加号的作用相反,不过它唯一能影响的就是把较小的数值类型自动转换为 int 类型
布尔值只能表示 true 或 false,所以比较它们之间的“大于”或“小于”没有意义
== 和 != 比较的是对象引用,所以比较两个对象的内容是否相同必须使用所有对象(不包括基本类型)中都存在的 equals() 方法
2.4 逻辑运算符
- 作用
每个逻辑运算符&&
(AND)、||
(OR)和!
(非)根据参数的逻辑关系生成布尔值 true 或 false。在 Java 逻辑运算中,不能像 C/C++ 那样使用非布尔值, 而仅能使用 AND、 OR、 NOT。
如果在预期为 String 类型的位置使用 boolean 类型的值,则结果会自动转为适当的文本格式(即 “true” 或 “false” 字符串)。
“短路”(short-circuiting)
整个表达式会在运算到可以明确结果时就停止并返回结果,这意味着该逻辑表达式的后半部分不会被执行到
2.5 字面值常量(Literal)
向程序中插入一个字面值常量时,编译器会确切地识别它的类型。当类型不明确时,必须辅以字面值常量关联来帮助编译器识别。
在文本值的后面添加字符可以让编译器识别该文本值的类型。对于 Long 型数值,结尾使用大写 L 或小写 l 皆可(不推荐使用 l,因为容易与阿拉伯数值 1 混淆)。大写 F 或小写 f 表示 float 浮点数。大写 D 或小写 d 表示 double 双精度。
十六进制(以 16 为基数),适用于所有整型数据类型,由前导 0x 或 0X 表示,后跟 0-9 或 a-f (大写或小写)
八进制(以 8 为基数)由 0~7 之间的数字和前导零 0 表示
Java 7 引入了二进制的字面值常量,由前导 0b 或 0B 表示,它可以初始化所有的整数类型。使用整型数值类型时,显示其二进制形式会很有用。在 Long 型和 Integer 型中这很容易实现,调用其静态的 toBinaryString() 方法即可。若将较小的类型传递给 Integer.tobinarystring() 时,类型将自动转换为 int
Java 7 中有一个深思熟虑的补充:我们可以在数字字面量中包含下划线_,以使结果更清晰
仅限单 _,不能多条相连
数值开头和结尾不允许出现 _
F、D 和 L的前后禁止出现 _
二进制前导 b 和 十六进制 x 前后禁止出现 _
指数计数法
"e" 表示 10 的几次幂
2.6 位运算符
对两个整数对应的位执行布尔代数,从而产生结果。源自 C 语言的底层操作,嵌入式开发中经常要直接操纵硬件,频繁设置硬件寄存器内的二进制位。Java 的设计初衷是电视机顶盒嵌入式开发,所以这种底层的操作仍被保留了下来。
2.7 移位运算符
对象也是二进制的“位”。只能用于处理整数类型
左移位运算符 << 能将其左边的运算对象向左移动右侧指定的位数(在低位补 0)
右移位运算符 >> 则相反,右移位运算符有“正”、“负”值:若值为正,则在高位插入 0;若值为负,则在高位插入 1。Java 也添加了一种“不分正负”的右移位运算符(>>>),它使用了“零扩展”(zero extension):无论正负,都在高位插入 0。这一运算符是 C/C++ 没有的。
2.8 三元运算符
也称为条件运算符。
布尔表达式 ? 值 1 : 值 2 若表达式计算为 true,则返回结果 值 1 ;如果表达式的计算为 false,则返回结果 值 2。
当然,也可以换用普通的 if-else 语句(在后面介绍),但三元运算符更加简洁
2.9 字符串运算符
这个运算符在 Java 里有一项特殊用途:连接字符串。
若表达式以一个 String 类型开头(编译器会自动将双引号 ""
标注的的字符序列转换为字符串),那么后续所有运算对象都必须是字符串。
2.10 类型转换
作用
与一个模型匹配。在适当的时候,Java 会将一种数据类型自动转换成另一种。除了布尔类型的数据,Java 允许任何基本类型的数据转换为另一种基本类型的数据
可以在程序未自动转换时显式、强制地使此类型发生转换。要执行强制转换,需要将所需的数据类型放在任何值左侧的括号内。
为了程序逻辑清晰或提醒自己,也可以使用显式类型转换。在其他情况下,类型转换型只有在代码编译时才显出其重要性。
2.11 类型提升
表达式中最大的数据类型是决定表达式结果的数据类型。
对小于 int 的基本数据类型(即 char、byte 或 short)执行任何算术或按位操作,这些值会在执行操作之前类型提升为 int,并且结果值的类型为 int。若想重新使用较小的类型,必须使用强制转换(由于重新分配回一个较小的类型,结果可能会丢失精度)。Java 不需要 sizeof() 方法,因为所有类型的大小在不同平台上是相同的。