Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't the compiler/JVM just make autoboxing "just work"?

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)

like image 500
Pyrolistical Avatar asked Apr 08 '10 19:04

Pyrolistical


People also ask

What is the major advantage of Autoboxing?

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.

What is the use of Autoboxing in Java?

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.

How does Autoboxing of integer work in Java?

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?

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.


2 Answers

  • Why did they do it this way?

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.

  • Why don't they just cache all Integers used by the program?

All Integers cannot be cached, because the memory implications would be enormous.

  • Why doesn't the JVM always auto unbox to primitive?

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.

like image 189
Jon Quarfoth Avatar answered Oct 13 '22 20:10

Jon Quarfoth


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.

like image 22
Tom Hawtin - tackline Avatar answered Oct 13 '22 19:10

Tom Hawtin - tackline