Implementing equals
int
, boolean
, and so on) and corresponding wrapper objects
(Integer
, Boolean
, and so on).
Boxing allows some code to be a bit more concise and legible.
It's also useful when using collections (which only take objects, not primitives).
There are two complimentary aspects of boxing:
int
to
an Integer
, for exampleBoolean
to a boolean
, for exampleBoxing partially hides the distinction between primitives and corresponding wrapper objects, but it doesn't remove it. There are two distinctions which are not changed by boxing:
null
, while primitives cannot
Some points to remember:
null
s. Auto-unboxing a null
object will cause a NullPointerException
.==
and equals
must be done with care.
If x
and y
are either both primitives, or both objects, then no boxing occurs:
Operation | Two primitives |
Two objects |
x == y |
compare value | compare identity |
x.equals(y) |
does not compile | compare value |
If one item is a primitive, and the other item is a corresponding wrapper object, then boxing can occur:
Operation | Behavior |
x == y |
treat as two primitives, and compare value |
x.equals(y) |
does not compile if x is a primitive; otherwise treat as two objects, and compare value |
Example
public final class BoxingExamples { public static final void main(String... args){ //pass Integer where int expected explode(Integer.valueOf(3)); //pass literal where Boolean expected tellTruth(true); //calculate "int-erchangably" with int and Integer Integer integerYear = Integer.valueOf(1989); Integer otherIntegerYear = integerYear + 10; int intYear = integerYear + Integer.valueOf(15); log(integerYear.toString()); log(otherIntegerYear.toString()); System.out.println(intYear); /* * Comparison of primitives and wrapper objects using == and equals. * * When both items are of the same type : * 2 primitives 2 objects * ---------------------------------------------------------- * == : value identity * equals() : not applicable value * * * When one item is a primitive, and the other is an object : * == : treat as two primitives * x.equals(y) : treat as two objects; do not compile if x is primitive */ intYear = 1880; integerYear = Integer.valueOf(1880); if (intYear == integerYear){ log("intYear == integerYear: TRUE"); // yes } else { log("intYear == integerYear : FALSE"); } if (integerYear.equals(intYear)){ log("integerYear.equals(intYear): TRUE"); //yes } else { log("integerYear.equals(intYear): FALSE"); } //does not compile "int cannot be dereferenced" : //intYear.equals(integerYear); intYear = 1881; //new value if (intYear == integerYear){ log("intYear == integerYear: TRUE"); } else { log("intYear == integerYear : FALSE"); // yes } if (integerYear.equals(intYear)){ log("integerYear.equals(intYear): TRUE"); } else { log("integerYear.equals(intYear): FALSE"); //yes } } // PRIVATE private static void explode(int numTimes){ log("Exploding " + numTimes + " times."); } private static void tellTruth(Boolean choice){ //instead of if ( aChoice.booleanValue() ) { if (choice) { log("Telling truth."); } else { log("Lying like a rug."); } } private static void log(String text){ System.out.println(text); } }
>java -classpath . BoxingExamples
Exploding 3 times.
Telling truth.
1989
1999
2004
intYear == integerYear: TRUE
integerYear.equals(intYear): TRUE
intYear == integerYear : FALSE
integerYear.equals(intYear): FALSE