Difference between revisions of "Java gotchas"

From OWASP
Jump to: navigation, search
(Incrementing values)
(Added link to JLS 5.1.7)
Line 23: Line 23:
 
  i and p contain the same value.
 
  i and p contain the same value.
 
   
 
   
The code above shows that i == p because the values are first unboxed into the primitive int type, and then the comparison is performed.  But this is only true for Integer values > -127 and < 127!  In other words, if the above example is changed so that i = 200 and p = 200, then i == p evaluates to false and the output would be:
+
The code above shows that i == p because the values are first unboxed into the primitive int type, and then the comparison is performed.  But this is only true for Integer values >= -128 and <= 127!  In other words, if the above example is changed so that i = 200 and p = 200, then i == p evaluates to false and the output would be:
 
  i and p are different.
 
  i and p are different.
 
  i and p contain the same value.
 
  i and p contain the same value.
 +
 +
This behavior is documented in the [http://java.sun.com/docs/books/jls Java Language Specification] [http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7 section 5.1.7]. Quoting from there:
 +
:If the value ''p'' being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let ''r1'' and ''r2'' be the results of any two boxing conversions of ''p''. It is always the case that ''r1'' == ''r2''.
  
 
Notice in the above example that the declaration was:
 
Notice in the above example that the declaration was:

Revision as of 15:34, 22 June 2007

Equality

Object equality is tested using the == operator, while value equality is tested using the .equals(Object) method. For example:

String one = new String("abc");
String two = new String("abc");
String three = one;
if (one != two) System.out.println("The two objects are not the same.");
if (one.equals(two)) System.out.println("But they do contain the same value");
if (one == three) System.out.println("These two are the same, because they use the same reference.");

The output is:

The two objects are not the same.
But they do contain the same value
These two are the same, because they use the same reference.

Autoboxing

Java 5's autoboxing and unboxing features add some new gotchas to testing for equality. Consider the following example:

Integer i = 100;
Integer p = 100;
if (i == p)  System.out.println("i and p are the same.");
if (i != p)   System.out.println("i and p are different.");	
if(i.equals(p))  System.out.println("i and p contain the same value.");

The output is:

i and p are the same.
i and p contain the same value.

The code above shows that i == p because the values are first unboxed into the primitive int type, and then the comparison is performed. But this is only true for Integer values >= -128 and <= 127! In other words, if the above example is changed so that i = 200 and p = 200, then i == p evaluates to false and the output would be:

i and p are different.
i and p contain the same value.

This behavior is documented in the Java Language Specification section 5.1.7. Quoting from there:

If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

Notice in the above example that the declaration was:

Integer i = 100;

If this had been:

Integer i = new Integer(100);

Then the output would have been different:

i and p are different.
i and p contain the same value.

Incrementing values

Be careful of the post-increment operator:

 int x = 5;
 x = x++;
 System.out.println( x );

Prints 5.