Search code examples
javajavacprimitiveboxing

Javac and Primitives: Boxed vs. Unboxed


My question is: why do primitive types have to be wrapped in an object, when it is also a possibility to have the compiler set things right for you?

  1. calls to a primitive value x's methods can be translated from x.call() to X.call(x) - this is what I try to illustrate below.
  2. generics aren't kept around at runtime (right?), so it isn't the case that you need to access class information at runtime - you could simply replace every instance of Integer by int and rewrite method calls as above, and end up with executable code.

So basically, what I'm asking is: what am I missing here?


I've been wondering about this for some time: Why can't the Java compiler translate...

int a = 482;
int b = 12;
System.out.println((a + b).toHexString());

...to the following code...

int a = 482;
int b = 12;
System.out.prinln(Ints.toHexString(a + b));

...and thus remove the entire need for boxing and unboxing?

(Thus, compile method calls to (static) function calls, and keep a single instance of Int.class around in case it's needed - e.g. after a call of Ints.getClass(_)?)


Comment added for clarity:

@Adam: No, I do not think it causes boxing/unboxing. The example attempts to illustrate how primitives could be treated as objects in the language, but as primitives by the compiler. This would remove the (slight) overhead in runtime, and a confusing thing in the language. Therefore the intended question was exactly: why didn't the extremely talented compiler developers pick this solution? Because if they didn't, there must be a clear impossibility that I'm not seeing. And I'd like to know what it is. – Pepijn


Solution

  • I presume you meant Integer.toHexString, not Ints.toHexString. The latter is not part of java.lang and the compiler would have no way to know anything about it.

    In theory, the compiler could translate calls of (a + b).toHexString() to Integer.toHexString(a + b), if the Java language specifies such a translation. (For example, auto-boxing of an int a to an Integer is specified to be Integer.valueOf(a).)

    I guess the Java language maintainers decided that that is too "magical" for Java programmers---in all versions of Java, primitive types do not have methods or fields. Java, in general, is designed to avoid syntactic sugar---that is why it's generally more verbose than most other languages.