Operators
运算符
The usual arithmetic operators + – * / are used in Java for addition, subtraction, multiplication, and division. The / operator denotes integer division if both arguments are integers, and floating-point division otherwise. Integer remainder (sometimes called modulus) is denoted by %. For example, 15 / 2 is 7, 15 % 2 is 1, and 15.0 / 2 is 7.5.
通常的运算符 + – * / 在Java中也被用作加、减、乘、除。如果除数和被除数都是整数,则运算符 /表示整除法(商为整数),否则为浮点除法。整除取余(有的时候叫“模”)用 %来表示。例如,15 / 2等于7,15 % 2等于1,而15.0 / 2等于7.5。
Note that integer division by 0 raises an exception, whereas floating-point division by 0 yields an infinite or NaN result.
注意整数被0除会引发异常,然而浮点数被0除则得到无穷(infinite)或无意义(NaN)的结果。
There is a convenient shortcut for using binary arithmetic operators in an assignment. For example,
在赋值时使用二元运算符有一个快捷的办法。例如:
x += 4;
is equivalent to
等价于
x = x + 4;
(In general, place the operator to the left of the = sign, such as *= or %=.)
(大体上是,将运算符放在符号 = 的左侧,就好像 *= 或是 %=。)
注释
Increment and Decrement Operators
递加和递减运算符
Programmers, of course, know that one of the most common operations with a numeric variable is to add or subtract 1. Java, following in the footsteps of C and C++, has both increment and decrement operators: n++ adds 1 to the current value of the variable n, and n-- subtracts 1 from it. For example, the code
程序员们当然知道对一个数字变量最普遍的操作之一就是加或是减1。Java,参照C和C++中的步长值,也有递加和递减运算符:n++在变量n的当前值上加1,而n--是在之上减1。例如,代码
int n = 12;
n++;
changes n to 13. Because these operators change the value of a variable, they cannot be applied to numbers themselves. For example, 4++ is not a legal statement.
使n变成13。因为这些运算符改变的是变量的值,他们并不适用于数字本身。例如,4++不是合法的语句。
There are actually two forms of these operators; you have seen the "postfix" form of the operator that is placed after the operand. There is also a prefix form, ++n. Both change the value of the variable by 1. The difference between the two only appears when they are used inside expressions. The prefix form does the addition first; the postfix form evaluates to the old value of the variable.
事实上这些运算符有两种运用格式;你在前面看到过的是将运算符放在操作数后面的“后缀”式。还有一种前缀式,++n。两种都是使变量的值改变1。两者的不同仅仅是在他们被用在表达式中的时候出现。前缀格式先进行累加;后缀格式则先取变量的原值。
int m = 7;
int n = 7;
int a = 2 * ++m; // now a is 16, m is 8 现在a是16,m是8
int b = 2 * n++; // now b is 14, n is 8 现在b是14,n是8
We recommend against using ++ inside other expressions because this often leads to confusing code and annoying bugs.
我们并不建议在其他表达式中使用++,因为这样常常会导致混乱的代码和恼人的bug。
(Of course, while it is true that the ++ operator gives the C++ language its name, it also led to the first joke about the language. C++ haters point out that even the name of the language contains a bug: "After all, it should really be called ++C, because we only want to use a language after it has been improved.")
(当然,C++语言确实是因操作符++而得名的,但这时它也导致了第一个关于C++语言的笑话。痛恨C++的人指出,甚至这个语言的名字就包含一个bug:“毕竟,它其实应该被叫做++C,因为我们只希望在他被改良后再使用这个语言。”)
Relational and boolean Operators
关系和boolean运算符
Java has the full complement of relational operators. To test for equality you use a double equal sign, ==. For example, the value of
Java具有关系运算符的完整补充。测试相等关系要使用“双等于号” == 。例如,
3 == 7
is false.
的值是false。
Use a != for inequality. For example, the value of
用 != 表示不相等。例如,
3 != 7
is true.
的值是true。
Finally, you have the usual < (less than), > (greater than), <= (less than or equal), and >= (greater than or equal) operators.
最后,你还可以使用常见的<(小于)、>(大于)、<=(小于等于)和 >=(大于等于)运算符。
Java, following C++, uses && for the logical "and" operator and || for the logical "or" operator. As you can easily remember from the != operator, the exclamation point ! is the logical negation operator. The && and || operators are evaluated in "short circuit" fashion. The second argument is not evaluated if the first argument already determines the value. If you combine two expressions with the && operator,
Java,参照C++,使用&&作为逻辑“与”运算符,||作为逻辑“或”运算符。与你很容易记住的!=运算符一样,感叹号!是逻辑非运算符。&&和||运算符使用“短路”方式求值。如果第一个参数已经确定表达式的值,则第二个参数就不被求值了。如果你用&&运算符将两个表达式联起来,
expression1 && expression2
and the truth value of the first expression has been determined to be false, then it is impossible for the result to be TRue. Thus, the value for the second expression is not calculated. This behavior can be exploited to avoid errors. For example, in the expression
并且第一个表达式的真值已经确定是false,则它就不可能得到TRue的结果。因此,第二个表达式的值就不被计算了。采用这种办法可以避免出错。例如,在表达式
x != 0 && 1 / x > x + y // no division by 0 避免被0除
the second part is never evaluated if x equals zero. Thus, 1 / x is not computed if x is zero, and no divide-by-zero error can occur.
中,只要x等于零,则第二个部分就永不会被求值。因此,如果x是零,1 / x就不会计算,也就不会发生被零除出错。
Similarly, the value of expression1 || expression2 is automatically true if the first expression is true, without evaluation of the second expression.
同样的,如果第一个表达式是true,就不会计算第二个表达式的值而自动得出expression1 || expression2的值true。
Finally, Java supports the ternary ?: operator that is occasionally useful. The expression
最后,Java支持偶尔会用到的三元运算符?:。表达式
condition ? expression1 : expression2
evaluates to the first expression if the condition is TRue, to the second expression otherwise. For example,
如果条件(condition)是TRue,则求第一个表达式的值,否则求第二个表达式。例如,
x < y ? x : y
gives the smaller of x and y.
给出x和y中较小的。
Bitwise Operators
位运算符
When working with any of the integer types, you have operators that can work directly with the bits that make up the integers. This means that you can use masking techniques to get at individual bits in a number. The bitwise operators are
当你使用任何一种整数类型时,都可以使用能对组成整数的二进制位直接起作用的运算符。这意味着你可以通过掩码技术得到数字中特定的二进制位。位运算符是
& ("and") | ("or") ^ ("xor") ~ ("not")
These operators work on bit patterns. For example, if n is an integer variable, then
这些运算符对二进制位结构起作用。例如,如果n是一个整型变量,那么
int fourthBitFromRight = (n & 8) / 8;
gives you a 1 if the fourth bit from the right in the binary representation of n is 1, and 0 if not. Using & with the appropriate power of 2 lets you mask out all but a single bit.
如果n的二进制表示的右数第四位是1,则得到1,否则是0。用&和适当的2的幂同时使用可以屏蔽掉除了特定位以外的所有二进制位。
注释
| When applied to boolean values, the & and | operators yield a boolean value. These operators are similar to the && and || operators, except that the & and | operators are not evaluated in "short circuit" fashion. That is, both arguments are first evaluated before the result is computed. 当&和|运算符应用于boolean值时,就会得到boolean值。这些运算符除了不用“短路”方式求值外,其它与&&和||运算符一样。换句话说,在计算结果之前,两个参数都要先被求值。 |
There are also >> and << operators, which shift a bit pattern to the right or left. These operators are often convenient when you need to build up bit patterns to do bit masking:
还有>>和<<运算符,用来向右或向左移动二进制位结构。这些运算符经常会在建立用于位屏蔽的位结构时为你带来便利:
int fourthBitFromRight = (n & (1 << 3)) >> 3;
Finally, a >>> operator fills the top bits with zero, whereas >> extends the sign bit into the top bits. There is no <<< operator.
最后,>>>运算符用零来填充最高位,而>>扩展符号位到最高位中。没有<<<运算符。
警告
C++注释
Mathematical Functions and Constants
数学函数和常量
The Math class contains an assortment of mathematical functions that you may occasionally need, depending on the kind of programming that you do.
Math类包含一个分类的数学函数,你可能偶尔会用到,这取决于你所做的程序的类型。
To take the square root of a number, you use the sqrt method:
求一个数的平方根,你要用sqrt方法:
double x = 4;
double y = Math.sqrt(x);
System.out.println(y); // prints 2.0 打印输出2.0
NOTE
注释
| There is a subtle difference between the println method and the sqrt method. The println method operates on an object, System.out, defined in the System class. But the sqrt method in the Math class does not operate on any object. Such a method is called a static method. You can learn more about static methods in Chapter 4. 在println方法和sqrt方法之间有一个细微的差别。println方法对一个在System类中定义的对象System.out起作用。但在Math类中的sqrt方法不对任何对象起作用。这样的方法叫做静态方法。你会在第4章中学到关于静态方法的更多内容。 |
The Java programming language has no operator for raising a quantity to a power: you must use the pow method in the Math class. The statement
Java编程语言中没有计算乘方的运算符:你必须用Math类中的pow方法。语句
double y = Math.pow(x, a);
sets y to be x raised to the power a (xa). The pow method has parameters that are both of type double, and it returns a double as well.
令y等于x的a次幂(xa)。pow方法的两个参数都是double类型,并且返回的也是double类型。
The Math class supplies the usual trigonometric functions
Math类还提供了常见的三角函数
Math.sin
Math.cos
Math.tan
Math.atan
Math.atan2
and the exponential function and its inverse, the natural log:
以及指数函数和它的反函数,自然对数:
Math.exp
Math.log
Finally, two constants denote the closest possible approximations to the mathematical constants p and e:
最后,还有两个常量来表示最接近数学常量p和e的可能近似值。
Math.PI
Math.E
TIP
提示
| Starting with JDK 5.0, you can avoid the Math prefix for the mathematical methods and constants by adding the following line to the top of your source file: 从JDK5.0开始,通过在源文件的最开始加上下面一行,你便可以在使用数学方法和常量时省略前缀Math: import static java.lang.Math.*;
For example, 例如, System.out.println("The square root of /u03C0 is " + sqrt(PI));
We discuss static imports in Chapter 4. 我们在第4章讨论静态输入。 |
NOTE
注释
| The functions in the Math class use the routines in the computer's floating-point unit for fastest performance. If completely predictable results are more important than fast performance, use the StrictMath class instead. It implements the algorithms from the "Freely Distributable Math Library" fdlibm, guaranteeing identical results on all platforms. See http://www.netlib.org/fdlibm/index.html for the source of these algorithms. (Whenever fdlibm provides more than one definition for a function, the StrictMath class follows the IEEE 754 version whose name starts with an "e".) Math类中的函数使用计算机浮点单元里的例程以得到最快的性能。如果完全可重复的结果比快速的性能更重要的话,可以改用StrictMath类。它执行“自由可分类数学库” fdlibm中的算法,保证在所有的平台上都得到相同的结果。这些算法的源代码参见http://www.netlib.org /fdlibm/index.html 。(只要fdlibm为函数提供了不只一个定义,StrictMath类都要参照名字以“e”开头的IEEE 754版本(译者:翻译水平有限,不知所云)。 |
Conversions Between Numeric Types
数值类型间的转换
It is often necessary to convert from one numeric type to another. Figure 3-1 shows the legal conversions.
从一种数值类型转换到另一种数值类型是常常需要做的。图3-1所示为合法转换。
Figure 3-1. Legal conversions between numeric types
图3-1 数值类型间的合法转换
The six solid arrows in Figure 3-1 denote conversions without information loss. The three dotted arrows denote conversions that may lose precision. For example, a large integer such as 123456789 has more digits than the float type can represent. When the integer is converted to a float, the resulting value has the correct magnitude but it loses some precision.
图3-1中的六个实线箭头表示无信息丢失的转换。三个虚线箭头表示转换可能丢失精度。例如,像123456789这样的长整型数比float类型所能代表的数字要多。当一个整型数转换成float时,得到的值虽然数量级正确,但丢失了一些精度。
int n = 123456789;
float f = n; // f is 1.23456792E8 f是1.23456792E8
When two values with a binary operator (such as n + f where n is an integer and f is a floating-point value) are combined, both operands are converted to a common type before the operation is carried out.
当两个值用二元运算符(就像n + f,这里n是整型数而f是浮点数)组合起来的时候,两个操作数在运算完成前都被转换成一个公共的类型。
· If either of the operands is of type double, the other one will be converted to a double.
· 如果任一个操作数是double类型,则另一个被转换成double类型。
· Otherwise, if either of the operands is of type float, the other one will be converted to a float.
· 否则,如果任一个操作数是float类型,则另一个被转换成float类型。
· Otherwise, if either of the operands is of type long, the other one will be converted to a long.
· 否则,如果任一个操作数是long类型,则另一个被转换成long类型。
· Otherwise, both operands will be converted to an int.
· 否则,两个操作数都被转换成int类型。
Casts
强制转换
In the preceding section, you saw that int values are automatically converted to double values when necessary. On the other hand, there are obviously times when you want to consider a double as an integer. Numeric conversions are possible in Java, but of course information may be lost. Conversions in which loss of information is possible are done by means of casts. The syntax for casting is to give the target type in parentheses, followed by the variable name. For example:
在前面一节,你看到int值在必要的时候会自动转换成double值。另一方面,显然你也有要将一个整数看成是double类型的时候。数值转换在Java中是可能的,但当然信息可能会丢失。可能会使信息丢失的转换依靠强制转换来完成。强制转换的语法是将目标类型放在圆括号中,后面紧接变量名。例如:
double x = 9.997;
int nx = (int) x;
Then, the variable nx has the value 9 because casting a floating-point value to an integer discards the fractional part.
于是,变量nx的值是9,因为将一个浮点值强制转换成一个整数而放弃小数部分。
If you want to round a floating-point number to the nearest integer (which is the more useful operation in most cases), use the Math.round method:
如果你想要将一个浮点数舍入到最接近的整数(这在大多数情况下都比较有用),就用Math.round方法:
double x = 9.997;
int nx = (int) Math.round(x);
Now the variable nx has the value 10. You still need to use the cast (int) when you call round. The reason is that the return value of the round method is a long, and a long can only be assigned to an int with an explicit cast because there is the possibility of information loss.
现在变量nx的值是10。当你调用round时,仍然需要使用强制转换(int)。原因是round方法返回的值是long类型,而long类型只能通过明确的强制转换被赋值给一个int类型,因为这有信息丢失的可能。
警告
| If you try to cast a number of one type to another that is out of the range for the target type, the result will be a truncated number that has a different value. For example, (byte) 300 is actually 44. 如果你试图将一个类型的超出目标类型取值范围的数强制转换成另一个类型,得到的结果就是一个被截短而具有不同值的数。例如,(byte) 300实际上是44。 |
C++ NOTE
C++注释
| You cannot cast between boolean values and any numeric type. This convention prevents common errors. In the rare case that you want to convert a boolean value to a number, you can use a conditional expression such as b ? 1 : 0. 你不能在boolean值和任意的数值类型之间强制转换。这个约定可以防止公共错误。在极少碰到的要将boolean值转换成数的情况下,你可以使用像b ? 1 : 0这样的表达式。 |
Parentheses and Operator Hierarchy
括号和运算层级
Table 3-4 shows the precedence of operators. If no parentheses are used, operations are performed in the hierarchical order indicated. Operators on the same level are processed from left to right, except for those that are right associative, as indicated in the table. For example, because && has a higher precedence than ||, the expression
表3-4所示为运算优先级。如果没有使用括号,则操作按照层级顺序所示去执行。同一层级的运算从左到右执行,除了那些表中指出右关联的之外。例如,因为&&具有比||较高的优先权,表达式
a && b || c
Table 3-4. Operator Precedence表3-4. 操作符优先级 | |
Operators 运算符 | Associativity 结合性 |
Left to right | |
! ~ ++ -- + (unary 一元) – (unary一元) () (cast 强制转换) new | Right to left |
* / % | Left to right |
+ - | Left to right |
Left to right | |
< <= > >= instanceof | Left to right |
== != | Left to right |
& | Left to right |
^ | Left to right |
| | Left to right |
&& | Left to right |
|| | Left to right |
?: | Right to left |
= += -= *= /= %= &= |= ^= <<= >>= >>>= | Right to left |
means
意思是
(a && b) || c
Because += associates right to left, the expression
因为+=是从右到左结合的,表达式
a += b += c
means
意思是
a += (b += c)
That is, the value of b += c (which is the value of b after the addition) is added to a.
也就是说,b += c的值(即做完加法后的b值)加到a上。
C++注释
Enumerated Types
枚举类型
Sometimes, a variable should only hold a restricted set of values. For example, you may sell clothes or pizza in four sizes: small, medium, large, and extra large. Of course, you could encode these sizes as integers 1, 2, 3, 4, or characters S, M, L, and X. But that is an error-prone setup. It is too easy for a variable to hold a wrong value (such as 0 or m).
有时,一个变量仅需要保留一组限定的值。例如,你可能卖四种尺寸的衣服或是比萨饼:小号、中号、大号和特大号。当然,你可以将这些号码用整数1、2、3、4或字符S、 M、 L、和 X来编码。但这是个容易出错的设置。对于一个变量,非常容易得到一个错误的值(就像0或者是m)。
Starting with JDK 5.0, you can define your own enumerated type whenever such a situation arises. An enumerated type has a finite number of named values. For example,
从JDK5.0开始,只要发生这种情况,你就可以定义你自己的枚举类型。一个枚举类型具有有限个指定的值。例如,
enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };
Now you can declare variables of this type:
现在你可以声明这种类型的变量:
Size s = Size.MEDIUM;
A variable of type Size can hold only one of the values listed in the type declaration or the special value null that indicates that the variable is not set to any value at all.
一个Size类型的变量只能保留类型声明列表中的某一个值,或者表示变量根本没有被设定任何值得特殊值null。
We discuss enumerated types in greater detail in Chapter 5.
我们在第5章会更详细的讨论枚举类型。