Autoboxing is rather scary. While I fully understand the difference between ==
and .equals
I can't but help have the follow bug the hell out of me:
final List<Integer> foo = Arrays.asList(1, 1000);
final List<Integer> bar = Arrays.asList(1, 1000);
System.out.println(foo.get(0) == bar.get(0));
System.out.println(foo.get(1) == bar.get(1));
That prints
true
false
Why did they do it this way? It something to do with cached Integers, but if that is the case why don't they just cache all Integers used by the program? Or why doesn't the JVM always auto unbox to primitive?
Printing false false or true true would have been way better.
EDIT
I disagree about breakage of old code. By having foo.get(0) == bar.get(0)
return true you already broke the code.
Can't this be solved at the compiler level by replacing Integer with int in byte code (as long as it is never assigned null)
Autoboxing and unboxing lets developers write cleaner code, making it easier to read. The technique lets us use primitive types and Wrapper class objects interchangeably and we do not need to perform any typecasting explicitly.
Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.
The automatic conversion of primitive data types into its equivalent Wrapper type is known as boxing and opposite operation is known as unboxing. This is the new feature of Java5. So java programmer doesn't need to write the conversion code.
Who is responsible for performing Autoboxing and unboxing in java? Java compiler is responsible for making such conversions. Before java 5 we used to write such code for performing Autoboxing.
Every Integer between -128 and 127 is cached by java. They did this, supposedly, for the performance benefit. Even if they wanted to go back on this decision now, it's unlikely that they would. If anyone built code depending on this, their code would break when it was taken out. For hobby coding, this perhaps doesn't matter, but for enterprise code, people get upset and lawsuits happen.
All Integers cannot be cached, because the memory implications would be enormous.
Because the JVM cannot know what you wanted. Also, this change could easily break legacy code not built to handle this case.
If the JVM to automatically unboxed to primitives on calls to ==, this issue will actually become MORE confusing. Now you need to remember that == always compares object references, unless the Objects can be unboxed. This would cause yet more weird confusing cases just like the one you stated above.
Rather then worry too hard about this, just remember this rule instead:
NEVER compare objects with == unless you intend to be comparing them by their references. If you do that, I can't think of a scenario in which you'd run into an issue.
Can you imagine how bad performance would be if every Integer
carried overhead for internment? Also does not work for new Integer
.
The Java language (not a JVM issue) cannot always auto unbox because code designed for pre-1.5 Java should still work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With