Java Reference
In-Depth Information
But values of type Complex are reference types, and every operation on Complex needs to do an
object allocation—dwarfing the cost of the two additions in add. What we need is a
primitive-type analog of Complex, perhaps called complex.
The issue here is that we want an “unboxed object,” and neither Java nor the JVM has any real
support for this. Now we can return to the lament, “Oh, but surely the compiler can optimize
this.” Sadly, this is much harder than it appears; although there is a compiler optimization based
on so-called escape analysis, which can sometimes determine that unboxing is okay, its
applicability is limited by Java's assumptions on Objects, which have been present since Java 1.1.
Consider the following puzzler:
double d1 = 3.14;
double d2 = d1;
Double o1 = d1;
Double o2 = d2;
Double ox = o1;
System.out.println(d1 == d2 ? "yes" : "no");
System.out.println(o1 == o2 ? "yes" : "no");
System.out.println(o1 == ox ? "yes" : "no");
The result is “yes”, “no”, “yes.” An expert Java programmer would probably say, “What silly code,
everyone knows you should use equals on the last two lines instead of ==.” But let us persist.
Even though all these primitives and objects contain the immutable value 3.14 and should really
be indistinguishable, the definitions of o1 and o2 create new objects, and the == operator
(identity comparison) can tell them apart. Note that on primitives, the identity comparison does
bitwise comparison but on objects it does reference equality. So often, we accidentally create a
new distinct Double object, which the compiler needs to respect because the semantics of Object,
from which Double inherits, require this. You've seen this discussion before, both in the earlier
discussion of value types and in chapter 14 , where we discussed referential transparency of
methods that functionally update persistent data structures.
Value types—not everything is a primitive or an object
We suggest that the resolution of this problem is to rework the Java assumptions (1) that
everything that isn't a primitive is an object and hence inherits Object, and (2) that all references
are references to objects.
The development starts like this. There are two forms of values: those of Object type that have
mutable fields unless forbidden with final, and those of identity, which may be tested with ==.
 
Search WWH ::




Custom Search