1. Overview
1.概述
In this tutorial, we’ll have a look at Java compound operators, their types and how Java evaluates them.
在本教程中,我们将看看Java复合运算符、它们的类型以及Java如何评估它们。
We’ll also explain how implicit casting works.
我们还将解释隐式铸造是如何工作的。
2. Compound Assignment Operators
2.复合赋值运算符
An assignment operator is a binary operator that assigns the result of the right-hand side to the variable on the left-hand side. The simplest is the “=” assignment operator:
赋值运算符是一个二进制运算符,它将右边的结果分配给左边的变量。最简单的是“=”赋值运算符。
int x = 5;
This statement declares a new variable x, assigns x the value of 5 and returns 5.
这个语句声明了一个新的变量x,给x赋值5并返回5。
Compound Assignment Operators are a shorter way to apply an arithmetic or bitwise operation and to assign the value of the operation to the variable on the left-hand side.
复合赋值运算符是应用算术或比特运算并将运算值赋给左侧变量的一种更简短的方法。
For example, the following two multiplication statements are equivalent, meaning a and b will have the same value:
例如,以下两个乘法语句是等价的,即a和b将有相同的值。
int a = 3, b = 3, c = -2;
a = a * c; // Simple assignment operator
b *= c; // Compound assignment operator
It’s important to note that the variable on the left-hand of a compound assignment operator must be already declared. In other words, compound operators can’t be used to declare a new variable.
值得注意的是,复合赋值运算符左边的变量必须是已经声明的。换句话说,复合运算符不能被用来声明一个新的变量。
Like the “=” assignment operator, compound operators return the assigned result of the expression:
与”=”赋值运算符一样,复合运算符返回表达式的赋值结果。
long x = 1;
long y = (x+=2);
Both x and y will hold the value 3.
x和y都将保持3的值。
The assignment (x+=2) does two things: first, it adds 2 to the value of the variable x, which becomes 3; second, it returns the value of the assignment, which is also 3.
赋值(x+=2)做了两件事:首先,它在变量x的值上加了2,变成3;其次,它返回赋值,也是3。
3. Types of Compound Assignment Operators
3.复合赋值运算符的类型
Java supports 11 compound assignment operators. We can group these into arithmetic and bitwise operators.
Java支持11个复合赋值运算符。我们可以将这些运算符分为算术运算符和位运算符。
Let’s go through the arithmetic operators and the operations they perform:
让我们来看看算术运算符和它们所进行的运算。
- Incrementation: +=
- Decrementation: -=
- Multiplication: *=
- Division: /=
- Modulus: %=
Then, we also have the bitwise operators:
然后,我们还有比特运算符。
- AND, binary: &=
- Exclusive OR, binary: ^=
- Inclusive OR, binary: |=
- Left Shift, binary: <<=
- Right Shift, binary: >>=
- Shift right zero fill: >>>=
Let’s have a look at a few examples of these operations:
让我们看一下这些操作的几个例子。
// Simple assignment
int x = 5; // x is 5
// Incrementation
x += 5; // x is 10
// Decrementation
x -= 2; // x is 8
// Multiplication
x *= 2; // x is 16
// Modulus
x %= 3; // x is 1
// Binary AND
x &= 4; // x is 0
// Binary exclusive OR
x ^= 4; // x is 4
// Binary inclusive OR
x |= 8; // x is 12
As we can see here, the syntax to use these operators is consistent.
正如我们在这里看到的,使用这些运算符的语法是一致的。
4. Evaluation of Compound Assignment Operations
4.复合分配操作的评估
There are two ways Java evaluates the compound operations.
Java有两种评估复合运算的方式。
First, when the left-hand operand is not an array, then Java will, in order:
首先,当左边的操作数不是一个数组时,那么Java将按顺序。
- Verify the operand is a declared variable
- Save the value of the left-hand operand
- Evaluate the right-hand operand
- Perform the binary operation as indicated by the compound operator
- Convert the result of the binary operation to the type of the left-hand variable (implicit casting)
- Assign the converted result to the left-hand variable
Next, when the left-hand operand is an array, the steps to follow are a bit different:
接下来,当左边的操作数是一个数组时,要遵循的步骤有点不同。
- Verify the array expression on the left-hand side and throw a NullPointerException or ArrayIndexOutOfBoundsException if it’s incorrect
- Save the array element in the index
- Evaluate the right-hand operand
- Check if the array component selected is a primitive type or reference type and then continue with the same steps as the first list, as if the left-hand operand is a variable.
If any step of the evaluation fails, Java doesn’t continue to perform the following steps.
如果评估的任何步骤失败,Java就不会继续执行下面的步骤。
Let’s give some examples related to the evaluation of these operations to an array element:
让我们举一些与这些操作对数组元素的评估有关的例子:。
int[] numbers = null;
// Trying Incrementation
numbers[2] += 5;
As we’d expect, this will throw a NullPointerException.
正如我们所期望的,这将抛出一个NullPointerException。
However, if we assign an initial value to the array:
然而,如果我们给数组分配一个初始值。
int[] numbers = {0, 1};
// Trying Incrementation
numbers[2] += 5;
We would get rid of the NullPointerException, but we’d still get an ArrayIndexOutOfBoundsException, as the index used is not correct.
我们将摆脱NullPointerException,但是我们仍然会得到ArrayIndexOutOfBoundsException,因为使用的索引不正确。
If we fix that, the operation will be completed successfully:
如果我们解决了这个问题,操作将成功完成。
int[] numbers = {0, 1};
// Incrementation
numbers[1] += 5; // x is now 6
Finally, the x variable will be 6 at the end of the assignment.
最后,x变量在作业结束时将是6。
5. Implicit Casting
5.隐性铸造
One of the reasons compound operators are useful is that not only they provide a shorter way for operations, but also implicitly cast variables.
复合运算符有用的原因之一是,它们不仅为操作提供了一种更短的方式,而且还隐含了对变量的铸造。
Formally, a compound assignment expression of the form:
从形式上看,一个复合赋值表达式的形式是:。
E1 op= E2
E1 on= E2
is equivalent to:
相当于。
E1 – (T)(E1 op E2)
E1-(T)(E1 op E2)。
where T is the type of E1.
其中T是E1的类型。
Let’s consider the following example:
让我们考虑下面的例子。
long number = 10;
int i = number;
i = i * number; // Does not compile
Let’s review why the last line won’t compile.
让我们回顾一下为什么最后一行不能编译。
Java automatically promotes smaller data types to larger data ones, when they are together in an operation, but will throw an error when trying to convert from larger to smaller types.
当较小的数据类型与较大的数据类型一起出现在一个操作中时,Java会自动将它们提升为较大的数据类型,但当试图从较大的类型转换为较小的类型时,会抛出一个错误。
So, first, i will be promoted to long and then the multiplication will give the result 10L. The long result would be assigned to i, which is an int, and this will throw an error.
因此,首先,i将被提升为long,然后乘法将得到10L.,long的结果将被分配给i,这是一个int,这将抛出一个错误。
This could be fixed with an explicit cast:
这可以通过明确的铸造来解决。
i = (int) i * number;
Java compound assignment operators are perfect in this case because they do an implicit casting:
Java复合赋值运算符在这种情况下是完美的,因为它们做了一个隐式铸造:。
i *= number;
This statement works just fine, casting the multiplication result to int and assigning the value to the left-hand side variable, i.
这条语句工作得很好,将乘法结果投给int,并将该值分配给左边的变量i。
6. Conclusion
6.结论
In this article, we looked at compound operators in Java, giving some examples and different types of them. We explained how Java evaluates these operations.
在这篇文章中,我们研究了Java中的复合运算符,给出了一些例子和不同的类型。我们解释了Java如何评估这些操作。
Finally, we also reviewed implicit casting, one of the reasons these shorthand operators are useful.
最后,我们还回顾了隐式铸造,这是这些速记运算符有用的原因之一。
As always, all of the code snippets mentioned in this article can be found in our GitHub repository.
一如既往,本文中提到的所有代码片段都可以在我们的GitHub仓库中找到。