Wednesday, August 18, 2010

Java Tid-bits

Wrapper classes and the == and != operator

Take the following code example:

Integer a = 130;
Integer b = 130;
if (a == b) {
    System.out.println("a == b");
}
Integer c = 100;
Integer d = 100;
if (c == d) {
    System.out.println("c == d");
}

Integer e = new Integer(100);
Integer f = new Integer(100);
if (e == f) {
    System.out.println("e == f");
}

What is output by the following code fragment? The answer is...

c == d

If the equals-equals operator evaluated to true for c==d why did it not for a==b? And furthermore, if c == d then why does e ==f evaluate to false?

This shows an interesting aspect of auto-boxing and the way Java manages/saves memory. The golden rule is that for the types Boolean, Byte, Character (\u0000 to \u007f), Short, and Integer (-128-127), if a variable is created by auto-boxing an evaluation of the == operator will return true for equal value items.

Your next question may be... "Well why is e == f evaluating to false?" This is because when we explicitly call the Integer constructor, passing it 100 we are bypassing the auto-box feature of java and therefore the rule doesn't apply.

PS: You should never rely on == for wrapped objects. Always use the .equals method!

Java Tid-bits

Method Overriding and Autoboxing

Java is full of little nuances. One interesting is the handling of overridden methods and the auto-boxing feature that was introduced in Java 1.5. For example suppose you had a class with the following methods..

public void doStuff(long myParam) {
    System.out.println("long");
}

public void doStuff(Integer myParam) {
    System.out.println("Integer");
}

Now take the following code block

int myInt = 4;
doStuff(myInt);
doStuff(3);

What would be output? The answer is...

long
long

Why is this? Well one might thing that Java will take myInt and automatically box it to be an Integer then call the method that accepts an Integer parameter. This is not the case. When autoboxing was introduced in Java 1.5 the designers wanted to make absolutely sure that legacy code (previous to Java 1.5) would still work as it always has. To guarantee this they had to make implicit casting favored over auto-boxing when overriding methods.