From different conbinations I have observed that in the above code for values of i1 and i2 between -128 to 127 ( range of byte ), i1 == i2 evaluates to true and for other values i1 == i2 evaluates to false.
First thing to say is that one should not be comparing Integer objects with == and expecting it to tell you whether they have equal numeric values. Use equals() for that.
When you use autoboxing to wrap int constants in Integer objects, you normally get a new Integer object. Thus, two autoboxings of the same value get different Integer objects, and == gives false (but equals() gives true, of course).
The JVM (or is it the compiler, I dunno) may use canonical cached objects for small values. That saves it from repeatedly creating new Integer objects for common values like -1, 0, 1, 2 etc. When this happens, two autoboxings of the same numeric value actually get the same object, so == tests true.
I think this is an internal implementation detail of a JVM, and I hope it is not standardised. Certainly, anyone who wrote a program that depended on this should be forced to write Perl, or whacked in the head (which would render them ideal for Perl programming...). [ August 03, 2007: Message edited by: Peter Chase ]
Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.
Oh, and coming back to the original question, since I got distracted: as Peter said, the unexpected behaviour is in the first example, not the second, and you should always be using .equals() regardless. Also note that in practice you won't know the value of the variable (otherwise why make it variable?) and therefore you wouldn't be counting on the behaviour seen anyway.
I would say it's partly specified in the JLS. That is, the JLS does specify that for all int values in the range -128 to 127, identical values must autobox to the same wrapper. However they do not specify exactly what happens outside this range. It would be perfectly legal for a particular JDK implementation to cache a larger range of wrapper values. So while you could depend on the fact that i1 == i2 when both are set to 100, you should not depend on the fact that i1 != i2 when both are set to 1000. It may be true for most (perhaps all) current JDKs, but it need not be true always.
Note that in current JDK implementations, Long wrappers are cached in the range -128 to 127, even though the JLS does not require this. So there is one example where the JDK exceeds the requirements of the JLS. Others may or may not occur in the future.
Overall though I would agree with Peter that even if some aspects of this behavior are guaranteed, it's probably a bad idea for programmers to rely on it. If only because this is the sort of trivia that's hard for programmers to remember, and other people reading your code may not be aware of it. Better to just avoid using == at all, where object wrappers are concerned.
"I'm not back." - Bill Harding, Twister
Fire me boy! Cool, soothing, shameless self promotion: