5 ms·
This is because Java cache the Integer objects from -128 to 127. So while it is correct that you should probably be more careful when dealing with Autoboxing (
by edwinnathaniel 15y ago
This is because Java cache the Integer objects from -128 to 127.
So while it is correct that you should probably be more careful when dealing with Autoboxing (or don't use it at all if you can...), there's one more layer deep that the article did not touch: the actual implementation of Java.
http://www.docjar.com/html/api/java/lang/Integer.java.html http://www.docjar.com/html/api/java/lang/Integer.java.html
Observe the IntegerCache inner class in particular:
"Cache to support the object identity semantics of autoboxing for values between -128 and 127 (inclusive) as required by JLS.
The cache is initialized on first usage. The size of the cache may be controlled by the -XX:AutoBoxCacheMax=<size> option."
- eropple 15y agoIIRC, this cache only works if you use Integer.valueOf instead of the constructor. (I could be misremembering, but the reason for that seems obvious to me.)
- masklinn 15y ago> the reason for that seems obvious to me. That Java's semantics force new object creation on constructor call, it's not possible to do otherwise (as opposed to, say, JavaScript, Python or Ruby in which object creation can be overridden and the "constructor" work like a factory methods, when it isn't one outright) (which it is in Python and Ruby)
- eropple 15y agoYes, exactly.
- masklinn 15y ago> the actual implementation of Java. > [...] > as required by JLS. If it's required by JLS, then it has to do with Java the language, it's got nothing to do with "the actual implementation of Java": this behavior is part of the semantics of java-the-language.
- edwinnathaniel 15y agoWhat I'm trying to say is that the article did not go deeper to the JLS level :D
- Someone 15y agoFor those wondering: http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7 http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#...: "If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2. Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references. This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K." When I first heard about that, I wondered why they would specifically specify that range in the language standard. Wouldn't it be better to describe the desired performance, and leave it at "implementations may choose to have boxing a given primitive value p, always yield the same reference, either for all values, or for some values"? Even if Sun's implementation used that trick to get sufficient performance in some part of the JDK, I do not think they should force everybody else to use it. Also, the way I read that first paragraph is that two primitive values p and q of the same type with identical small values may still get boxed to different references. I doubt anybody would implement it that way, though, and the second paragraph seems to be in disagreement with that by speaking of "certain common value_s_".