📄 chapter03.html
字号:
00001011110111111011101111111100
i ^ j, <font color=#0000ff>int</font>: 140491384, binary:
00001000010111111011101001111000
i << 5, <font color=#0000ff>int</font>: 1890614912, binary:
01110000101100000111111010000000
i >> 5, <font color=#0000ff>int</font>: 1846303, binary:
00000000000111000010110000011111
(~i) >> 5, <font color=#0000ff>int</font>: -1846304, binary:
11111111111000111101001111100000
i >>> 5, <font color=#0000ff>int</font>: 1846303, binary:
00000000000111000010110000011111
(~i) >>> 5, <font color=#0000ff>int</font>: 132371424, binary:
00000111111000111101001111100000</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The binary representation of the
numbers is referred to as
<A NAME="Index185"></A><A NAME="Index186"></A><I>signed two’s
complement</I>.</FONT><A NAME="_Toc375545256"></A><A NAME="_Toc408018457"></A><BR></P></DIV>
<A NAME="Heading112"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Ternary if-else
operator<A NAME="Index187"></A><A NAME="Index188"></A><A NAME="Index189"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This operator is unusual because it
has three operands. It is truly an operator because it produces a value, unlike
the ordinary if-else statement that you’ll see in the next section of this
chapter<A NAME="Index190"></A>. The expression is of the form
</FONT><BR><FONT FACE="Georgia"><I>boolean-exp</I> ? <I>value0</I> :
<I>value1</I></FONT><BR><FONT FACE="Georgia">If <I>boolean-exp</I>
evaluates to <B>true</B>, <I>value0</I> is evaluated and its result becomes the
value produced by the operator. If <I>boolean-exp</I> is <B>false</B>,
<I>value1</I> is evaluated and its result becomes the value produced by the
operator.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Of course, you could use an
ordinary <B>if-else </B>statement (described later), but the ternary operator is
much terser. Although C prides itself on being a terse language, and the ternary
operator might have been introduced partly for efficiency, you should be
somewhat wary of using it on an everyday basis – it’s easy to
produce unreadable code.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The conditional operator can be
used for its side effects or for the value it produces, but in general you want
the value since that’s what makes the operator distinct from the
<B>if-else</B>. Here’s an example:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>static</font> <font color=#0000ff>int</font> ternary(<font color=#0000ff>int</font> i) {
<font color=#0000ff>return</font> i < 10 ? i * 100 : i * 10;
} </PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can see that this code is more
compact than what you’d need to write without the ternary
operator:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>static</font> <font color=#0000ff>int</font> alternative(<font color=#0000ff>int</font> i) {
<font color=#0000ff>if</font> (i < 10)
<font color=#0000ff>return</font> i * 100;
<font color=#0000ff>return</font> i * 10;
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The second form is easier to
understand, and doesn’t require a lot more typing. So be sure to ponder
your reasons when choosing the ternary
operator.</FONT><A NAME="_Toc375545257"></A><A NAME="_Toc408018458"></A><BR></P></DIV>
<A NAME="Heading113"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
The comma operator<BR><A NAME="Index191"></A><A NAME="Index192"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The comma is used in C and C++ not
only as a separator in function argument lists, but also as an operator for
sequential evaluation. The sole place that the comma <I>operator</I> is used in
Java is in <B>for</B> loops, which will be described later in this
chapter.</FONT><A NAME="_Toc375545258"></A><A NAME="_Toc408018459"></A><BR></P></DIV>
<A NAME="Heading114"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
String operator +<BR><A NAME="Index193"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There’s one special usage of
an operator in Java: the <B>+</B> operator can be used to
<A NAME="Index194"></A>concatenate strings, as you’ve already seen. It
seems a natural use of the <B>+</B> even though it doesn’t fit with the
traditional way that <B>+</B> is used. This capability seemed like a good idea
in C++, so <A NAME="Index195"></A><A NAME="Index196"></A><I>operator
overloading</I> was added to C++ to allow the C++ programmer to add meanings to
almost any operator. Unfortunately, operator overloading combined with some of
the other restrictions in C++ turns out to be a fairly complicated feature for
programmers to design into their classes. Although operator overloading would
have been much simpler to implement in Java than it was in C++, this feature was
still considered too complex, so Java programmers cannot implement their own
overloaded operators as C++ programmers can.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The use of the <B>String +</B> has
some interesting behavior. If an expression begins with a <B>String</B>, then
all operands that follow must be <B>String</B>s:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>int</font> x = 0, y = 1, z = 2;
String sString = <font color=#004488>"x, y, z "</font>;
System.out.println(sString + x + y + z);</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here, the Java compiler will
convert <B>x</B>, <B>y</B>, and <B>z</B> into their <B>String</B>
representations instead of adding them together first. However, if you
say:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>System.out.println(x + sString);</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">earlier versions of Java will
signal an error. (Later versions, however, will turn <B>x </B>into a
<B>String.</B>) So if you’re putting together a <B>String</B> (using an
earlier version of Java) with addition, make sure the first element is a
<B>String</B> (or a quoted sequence of characters, which the compiler recognizes
as a
<B>String</B>).</FONT><A NAME="_Toc375545259"></A><A NAME="_Toc408018460"></A><BR></P></DIV>
<A NAME="Heading115"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Common pitfalls when using
operators<A NAME="Index197"></A><A NAME="Index198"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">One of the pitfalls when using
operators is trying to get away without parentheses when you are even the least
bit uncertain about how an expression will evaluate. This is still true in
Java.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">An extremely common error in C and
C++ looks like this:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>while</font>(x = y) {
<font color=#009900>// ....</font>
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The programmer was trying to test
for equivalence (<B>==</B>) rather than do an assignment. In C and C++ the
result of this assignment will always be <B>true</B> if <B>y </B>is nonzero, and
you’ll probably get an infinite loop. In Java, the result of this
expression is not a <B>boolean,</B> and the compiler expects a <B>boolean</B>
and won’t convert from an <B>int</B>, so it will conveniently give you a
compile-time error and catch the problem before you ever try to run the program.
So the pitfall never happens in <A NAME="Index199"></A>Java. (The only time you
won’t get a compile-time error is when <B>x</B> and <B>y</B> are
<B>boolean</B>, in which case <B>x = y</B> is a legal expression, and in the
above case, probably an error.)</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">A similar problem in C and C++ is
using bitwise AND and OR instead of logical. Bitwise AND and OR use one of the
characters (<B>&</B> or <B>|</B>) while logical AND and OR use two
(<B>&&</B> and <B>||</B>). Just as with <B>=</B> and <B>==</B>,
it’s easy to type just one character instead of
two.<A NAME="Index200"></A><A NAME="Index201"></A><A NAME="Index202"></A><A NAME="Index203"></A><A NAME="Index204"></A><A NAME="Index205"></A>
In Java, the compiler again prevents this because it won’t let you
cavalierly use one type where it doesn’t
belong.</FONT><A NAME="_Toc375545260"></A><A NAME="_Toc408018461"></A><BR></P></DIV>
<A NAME="Heading116"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Casting operators<A NAME="Index206"></A><A NAME="Index207"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The word <I>cast</I> is used in the
sense of “casting into a mold.” Java will automatically change one
type of data into another when appropriate. For instance, if you assign an
integral value to a floating-point variable, the compiler will automatically
convert the <B>int</B> to a <B>float</B>. Casting allows you to make this type
conversion explicit, or to force it when it wouldn’t normally
happen.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To perform a cast, put the desired
data type (including all modifiers) inside parentheses to the left of any value.
Here’s an example:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>void</font> casts() {
<font color=#0000ff>int</font> i = 200;
<font color=#0000ff>long</font> l = (<font color=#0000ff>long</font>)i;
<font color=#0000ff>long</font> l2 = (<font color=#0000ff>long</font>)200;
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As you can see, it’s possible
to perform a cast on a numeric value as well as on a variable. In both casts
shown here, however, the cast is superfluous, since the compiler will
automatically promote an <B>int</B> value to a <B>long</B> when necessary. You
can still put a cast in to make a point or to make your code more clear. In
other situations, a cast is essential just to get the code to
compile.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In C and C++, casting can cause
some headaches. In Java, casting is safe, with the exception that when you
perform a so-called <A NAME="Index208"></A><A NAME="Index209"></A><I>narrowing
conversion</I> (that is, when you go from a data type that can hold more
information to one that doesn’t hold as much) you run the risk of losing
information.<I> </I>Here the compiler forces you to do a cast, in effect saying
“this can be a dangerous thing to do – if you want me to do it
anyway you must make the cast explicit.” With a
<A NAME="Index210"></A><A NAME="Index211"></A><I>widening conversion</I> an
explicit cast is not needed because the new type will more than hold the
information from the old type so that no information is ever
lost.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Java allows you to cast any
primitive type to any other primitive type, except for
<A NAME="Index212"></A><B>boolean,</B> which doesn’t allow any casting at
all. Class types do not allow casting. To convert one to the other there must be
special methods. (<B>String</B> is a special case, and you’ll find out
later in the book that objects can be cast within a <I>family</I> of types; an
<B>Oak</B> can be cast to a <B>Tree</B> and vice-versa, but not to a foreign
type such as a <B>Rock.</B>)</FONT><BR></P></DIV>
<A NAME="Heading117"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Literals<BR><A NAME="Index213"></A></H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Ordinarily when you insert a
literal value into a program the compiler knows exactly what type to make it.
Sometimes, however, the type is ambiguous. When this happens you must guide the
compiler by adding some extra information in the form of characters associated
with the literal value. The following code shows these
characters:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Literals.java</font>
<font color=#0000ff>class</font> Literals {
<font color=#0000ff>char</font> c = 0xffff; <font color=#009900>// max char hex value</font>
<font color=#0000ff>byte</font> b = 0x7f; <font color=#009900>// max byte hex value</font>
<font color=#0000ff>short</font> s = 0x7fff; <font color=#009900>// max short hex value</font>
<font color=#0000ff>int</font> i1 = 0x2f; <font color=#009900>// Hexadecimal (lowercase)</font>
<font color=#0000ff>int</font> i2 = 0X2F; <font color=#009900>// Hexadecimal (uppercase)</font>
<font color=#0000ff>int</font> i3 = 0177; <font color=#009900>// Octal (leading zero)</font>
<font color=#009900>// Hex and Oct also work with long.</font>
<font color=#0000ff>long</font> n1 = 200L; <font color=#009900>// long suffix</font>
<font color=#0000ff>long</font> n2 = 200l; <font color=#009900>// long suffix</font>
<font color=#0000ff>long</font> n3 = 200;
<font color=#009900>//! long l6(200); // not allowed</font>
<font color=#0000ff>float</font> f1 = 1;
<font color=#0000ff>float</font> f2 = 1F; <font color=#009900>// float suffix</font>
<font color=#0000ff>float</font> f3 = 1f; <font color=#009900>// float suffix</font>
<font color=#0000ff>float</font> f4 = 1e-45f; <font color=#009900>// 10 to the power</font>
<font color=#0000ff>float</font> f5 = 1e+9f; <font color=#009900>// float suffix</font>
<font color=#0000ff>double</font> d1 = 1d; <font color=#009900>// double suffix</font>
<font color=#0000ff>double</font> d2 = 1D; <font color=#009900>// double suffix</font>
<font color=#0000ff>double</font> d3 = 47e47d; <font color=#009900>// 10 to the power</font>
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><A NAME="Index214"></A><FONT FACE="Georgia">Hexadecimal
(<A NAME="Index215"></A>base 16), which works with all the integr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -