Why Integer class caching values in the range -128 to 127?
Just wondering, why between -128 and 127?
A larger range of integers may be cached, but at least those between -128 and 127 must be cached because it is mandated by the Java Language Specification (emphasis mine):
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.
The rationale for this requirement is explained in the same paragraph:
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. [...]
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.
How can I cache other values outside of this range.?
You can use the -XX:AutoBoxCacheMax
JVM option, which is not really documented in the list of available Hotspot JVM Options. However it is mentioned in the comments inside the Integer
class around line 590:
The size of the cache may be controlled by the
-XX:AutoBoxCacheMax=<size>
option.
Note that this is implementation specific and may or may not be available on other JVMs.
Why is 128==128 false but 127==127 is true when comparing Integer wrappers in Java?
When you compile a number literal in Java and assign it to a Integer (capital I
) the compiler emits:
Integer b2 =Integer.valueOf(127)
This line of code is also generated when you use autoboxing.
valueOf
is implemented such that certain numbers are "pooled", and it returns the same instance for values smaller than 128.
From the java 1.6 source code, line 621:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
The value of high
can be configured to another value, with the system property.
-Djava.lang.Integer.IntegerCache.high=999
If you run your program with that system property, it will output true!
The obvious conclusion: never rely on two references being identical, always compare them with .equals()
method.
So b2.equals(b3)
will print true for all logically equal values of b2,b3.
Note that Integer
cache is not there for performance reasons, but rather to conform to the JLS, section 5.1.7; object identity must be given for values -128 to 127 inclusive.
Integer#valueOf(int) also documents this behavior:
this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
What are the benefits of IntegerCache while using Integer?
Values between -128 and 127 are cached for reuse. This is an example of the flyweight pattern, which minimizes memory usage by reusing immutable objects.
Beyond being an optimization, this behaviour is part of the JLS, so the following may be relied upon:
Integer a = 1;
Integer b = 1;
Integer c = 999;
Integer d = 999;
System.out.println(a == b); // true
System.out.println(c == d); // false
Integer comparison confusion
Values from -128 to 127
for int are cached for boxing. That's why the first comparison returns true
.
http://www.mohawksoft.org/?q=node/70
Integers caching in Java
I want to understand purposes of this
optimization. In what cases
performance is increased, etc.
Reference to some research of this
problem will be great.
The purpose is mainly to save memory, which also leads to faster code due to better cache efficiency.
Basically, the Integer
class keeps a cache of Integer
instances in the range of -128 to 127, and all autoboxing, literals and uses of Integer.valueOf()
will return instances from that cache for the range it covers.
This is based on the assumption that these small values occur much more often than other ints and therefore it makes sense to avoid the overhead of having different objects for every instance (an Integer
object takes up something like 12 bytes).
Integer object caching
You're misunderstanding what "the same object will be returned" means.
So, comparison with ==
is actually comparing memory locations, and returns true only when the two variables hold the same object (i.e. stored at the same memory location).
Values between -128 to 127 are stored in the integer constant pool, which means that every 10 is the same 10 (i.e. the same memory location), every 12 is the same 12, etc. But it's not the case that all 10s are also 12s, which is what your question is unintentionally assuming.
Anyway, once you get outside of that range, each primitive int is a new object and is assigned to a new memory location outside of the constant pool.
You can test that with the following code:
public static void main(String[] args) {
Integer a = 1000;
Integer b = 1000;
if(a == b)
System.out.println("same");
else
System.out.println("Not");
}
That will print "Not", because a
and b
are two different objects stored in different memory locations.
And this is why you should compare things with .equals()
How is it possible that 127==127 while 128!=128?
Because the Integer
type interns the values (by the static class IntegerCache
) from -128 to 127.
Related Topics
Java: How to Start a Standalone Application from the Current One When Both Are in the Same Package
How to Know If Other Threads Have Finished
How to Load a Jar File at Runtime
Http Servlet Request Lose Params from Post Body After Read It Once
Using Regex to Generate Strings Rather Than Match Them
Java: Insert Multiple Rows into MySQL with Preparedstatement
Eclipse Java Debugging: Source Not Found
Java Resultset How to Check If There Are Any Results
Difference Between @Mock and @Injectmocks
Can You Recommend a Java Library for Reading (And Possibly Writing) CSV Files
Differences Between Oracle Jdk and Openjdk
How to See Jit-Compiled Code in Jvm
How to Properly Override Clone Method
What Is the Default Initialization of an Array in Java
Do I Need <Class> Elements in Persistence.Xml
Java Generics: List, List<Object>, List<>
In Java, How to Convert a Byte Array to a String of Hex Digits While Keeping Leading Zeros