Java 复合赋值运算符
复合赋值运算符为分配算术或位运算符的结果提供了一种更简短的语法。它们在将结果分配给第一个操作数之前对两个操作数进行操作。
以下是java中所有可能的赋值运算符
所有复合赋值运算符的实现
输出:
解决复合赋值运算符的规则
在运行时,表达式以两种方式之一进行评估。这取决于编程条件。
- 如果左边的操作数表达式不是一个数组访问表达式,那么。
- 首先,左边的操作数被评估以产生一个变量。如果这个评估突然完成,那么赋值表达式也会因为同样的原因突然完成;右侧操作数没有被评估,也没有发生赋值。
- 否则,左手操作数的值被保存,然后右手操作数被评估。如果这个评估突然完成,那么赋值表达式也会因为同样的原因突然完成,不会发生赋值。
- 否则,左侧变量的保存值和右侧操作数的值被用来执行复合赋值运算符所指示的二进制操作。如果这个操作突然完成,那么赋值表达式也会因为同样的原因突然完成,不发生赋值。
- 否则,二进制操作的结果被转换为左侧变量的类型,经过价值集转换为适当的标准价值集,并且转换的结果被存储到该变量中。
- 如果左手操作数表达式是一个数组存取表达式,那么。
- 首先,对左手操作数组存取表达式的数组引用子表达式进行评估。如果这个评估突然完成,那么赋值表达式也会因为同样的原因突然完成;(左手操作数组访问表达式的)索引子表达式和右手操作数不被评估,也不会发生赋值。
- 否则,左手操作数组访问表达式的索引子表达式被评估。如果这个评估突然完成,那么赋值表达式也会因为同样的原因突然完成,右侧操作数不被评估,也不发生赋值。
- 否则,如果数组引用子表达式的值是空的,那么就不会发生赋值,并且抛出一个NullPointerException。
- 否则,数组引用子表达式的值确实指的是一个数组。如果索引子表达式的值小于零,或者大于等于数组的长度,那么就不会发生赋值,并且会抛出ArrayIndexOutOfBoundsException。
- 否则,索引子表达式的值被用来选择由数组引用子表达式的值所引用的数组中的一个组件。这个组件的值被保存起来,然后对右边的操作数进行评估。如果这个评估突然完成,那么赋值表达式也会因为同样的原因突然完成,不会发生赋值。
例子 :用复合赋值运算符解决语句 的问题
我们都知道,每当我们将一个较大的值赋给一个较小的数据类型的变量时,那么我们必须执行显式的类型转换以获得没有任何编译时错误的结果。如果我们不执行显式类型转换,那么我们就会出现编译时错误。但在复合赋值运算符的情况下,内部将自动进行类型转换,即使我们将一个较大的值赋给一个较小的数据类型变量,但可能会有数据信息丢失的机会。程序员将不负责执行明确的类型转换。让我们看看下面的例子,看看普通赋值运算符和复合赋值运算符之间的区别。
形式为E1 op= E2的复合赋值表达式等同于E1 = (T) ((E1) op (E2)),其中T是E1的类型,只不过E1只被评估一次。
例如,下面的代码是正确的。
并导致x的值为7,因为它相当于。
因为这里的6.6是double,会自动转换为short类型,不需要明确的类型转换。
请参考:什么时候需要进行类型转换 ?
输出:
解释: 在上面的例子中,我们使用的是普通的赋值运算符。在这里,我们将一个int(b+1=20)值赋给字节变量(即b),这导致了编译时错误。这里我们必须进行类型转换以得到结果。
输出:
解释: 在上面的例子中,我们正在使用复合赋值运算符。这里我们将一个int(b+1=20)值赋给字节变量(即b),除此之外,我们得到的结果是20,因为在复合赋值运算符中,类型转换由编译自动完成。在这里,我们不需要做类型转换来得到结果。
输出:
输出:
输出:
输出:
参考资料: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.2