On new Integer(...).intValue()



  • There're quite a lot of articles recently making fun of new Integer(...).intValue() constructs. However, before laughing out loudly take a look at this paragraph under 13.4.9 final Fields and Constants in Java Language Specification. Please read "We note, but do not recommend" as "Since we have screwed with ABI, here's a nasty workaround". WTF?

     (The real WTF are article comments of course.)



  • The section recommends doing something like 'new Boolean(true).booleanValue()' when you want to force a field to not be a compile-time constant.

    Why would you want to do this? Because changing a compile-time constant won't affect classes in other places which have not been re-compiled. For instance, if a bunch of classes are making use of Math.PI, then inspection of the bytecode will reveal that they are not accessing the java.lang.Math class at all; rather, the compiler replaced Math.PI with 3.141592653589... because it is a compile-time constant. So if a Sun engineer, driven mad by too much partying, decides to change Math.PI so it equals 3.00000, all the classes which have been using Math.PI will not be affected by that change and will continue to use the other value, unless and until they are recompiled.

    But if Math.PI were declared as 'public static final PI = new Double(3.141592653589).doubleValue()' then the compiler would not try to replace it with a constant, so any other classes which have been accessing Math.PI will always consult the actual java.lang.Math class of their classloader. (Yes, I know the compiler theoretically could still optimize that expression into a constant, but I'm pretty sure it refrains from doing so by design, so that constant-optimizations are predictable and relatively simple to understand.)

    If you had a constant which you believed was going to be subject to change, you might want to do the above in order to prevent other classes outside of your control from having a constant embedded in them and thus being insulated from whatever changes you might choose to make in the future.

    Of course, as the spec points out, it's far better to just have a static accessor method instead, like getPI().

    Back to the original 'new Integer(0).intValue()' post. That clearly is not a constant. It's a local variable in a method (or constructor or initializer). Section 13.4.9 can't possibly apply.



  • Interesting. I always figured that these values would be referenced all the time, instead of being optimized out like you said. I suppose this is one way to take care of a potential "oops"


Log in to reply