I was digging into how the Integer
class actually uses cached objects, and I found the below code in the Integer.valueOf
method:
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
My question is:
assert IntegerCache.high >= 127;
I read that
assert provides an effective way to detect and correct programming
errors. But this is runtime code so why would someone use assert?AssertionError
in this scenario?valueOf(int a) is an inbuilt method which is used to return an Integer instance representing the specified int value a. Parameters : The method accepts a single parameter a of integer type representing the parameter whose Integer instance is to be returned.
valueOf() returns an Integer object while Integer. parseInt() returns a primitive int. Both String and integer can be passed a parameter to Integer. valueOf() whereas only a String can be passed as parameter to Integer.
Integer class is a wrapper class for the primitive type int which contains several methods to effectively deal with an int value like converting it to a string representation, and vice-versa. An object of the Integer class can hold a single int value.
The java string valueOf() method converts different types of values into string. By the help of string valueOf() method, you can convert int to string, long to string, boolean to string, character to string, float to string, double to string, object to string and char array to string.
The purpose of asserts is to establish invariants and to document the implementation. Here, this assert documents the fact that when the valueOf
method is entered IntegerCache.high
value is guaranteed to be at least 127. It's better to write an assert instead of the comment, because the assert will also be checked by the JVM when the corresponding command line option (-esa
) is active.
Normally this assert will never throw, because the IntegerCache.high
is initialized in this way:
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
This code guarantees that the value will be at least 127. So the assert can throw if you modify IntegerCache.high
(using reflection and setAccessible(true)
) or if the JDK will be modified in the future and bug will be introduced in IntegerCache.high
initialization code. That's why asserts exist: to catch bugs.
The JLS mandates that the integer cache must be in place for integers between -128 and 127.
At present, the Oracle implementation enforces this but no more, so the cache ceiling could well be extended at some point in the future (unlikely in practice, but it'd be completely in spec.)
However, it can never be less than 127, otherwise the implementation would no longer conform to the JLS - and that would be a pretty big deal, hence (I believe) why the assert statement is there!
As biziclop pointed out in the comments, it can also be changed by the user by passing a VM argument - another (and perhaps more compelling) reason the assertion is in place.
Also note that the assert statement will be skipped unless running with -ea
, so in normal use there is absolutely no runtime overhead for this check.
The cache, normally for -128 ... 127, can be enlarged, which might be the reason: it should not become less. And as the code would function even without cache, an assert might be a soft way: telling about a performance defect when developing. As asserts do no impact on production code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With