Java Reference
In-Depth Information
< Day Day Up >
Puzzle 32: Curse of Looper
Provide declarations for
i
and
j
that turn this loop into an infinite loop:
while (i <= j && j <= i && i != j) {
}
Solution 32: Curse of Looper
Oh, no, not another seemingly impossible looper! If
i <= j
and
j <= i
, surely
i
must equal
j
? This
property certainly holds for the real numbers. In fact, it is so important that it has a name: The
relation on the real numbers is said to be
antisymmetric
. Java's
<=
operator used to be antisymmetric
before release 5.0, but no longer.
Until release 5.0, Java's
numerical comparison operators
(
<, <=
,
>
, and
>=
) required both of their
operands to be of a primitive numeric type (
byte
,
char
,
short
,
int
,
long
,
float
, or
double
) [JLS2
15.20.1]. In release 5.0, the specification was changed to say that the type of each operand must be
convertible to
a primitive numeric type [JLS 15.20.1, 5.1.8]. Therein lies the rub.
In release 5.0, autoboxing and auto-unboxing were added to the language. If you are unfamiliar with
them see:
http://java.sun.com/j2se/5.0/docs/guide/language/autoboxing.html
[Boxing]
. The
<=
operator is still antisymmetric on the set of primitive numeric values, but now it applies to operands
of
boxed numeric types
as well. (The boxed numeric types are
Byte
,
Character
,
Short
,
Integer
,
Long
,
Float
, and
Double
.) The
<=
operator is not antisymmetric on operands of these types, because
Java's
equality operators
(
==
and
!=
) perform reference identity comparison rather than value
comparison when applied to object references.
To make this concrete, the following declarations give the expression (
i <= j && j <= i && i !=
j
) the value
true
, turning the loop into an infinite loop:
Integer i = new Integer(0);
Integer j = new Integer(0);
The first two subexpressions (
i <= j
and
j <= i
) perform
unboxing conversions
[JLS 5.1.8] on
i
and
j
and compare the resulting
int
values numerically. Both
i
and
j
represent 0, so both of these
Search WWH ::
Custom Search