Well just for fun, I decided to take a shot at it.
Most probably what you’ve heard was that you could corrupt the Integer’s cache in order to do this.
Before getting any further, here’s the code:
package test;
import java.lang.reflect.Field;
public class BreakMath {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException {
Class<?> integerCache = Class.forName("java.lang.Integer$IntegerCache");
Field field = integerCache.getDeclaredField("cache");
field.setAccessible(true);
Integer[] cache = (Integer[]) field.get(null);
cache[1 + 128] = 2;
System.out.println(1 + 1);
System.out.println(1 + Integer.valueOf(1));
System.out.println(Integer.valueOf(1) + Integer.valueOf(1));
}
}
This outputs the following:
2
3
4
What is really happening?
You are not changing the 1 value in Java. What you are in fact is taking advantage of the internal cache that Integer.class has (in Oracle’s JVM and openJDK, might differ in other vendor’s JVMs)
Via reflection we get to the Integer cache and we change the value. Since then Integer.valueOf() uses that cache you can achieve this… but if you notice when you are doing the math with plain primitives it does not work.
It wouldn’t work as well if you had done new Integer(1) (since does not use the cache).
But anywhere you would have the JVM autoboxing you would get into this. So for example if you have the method
public static void printInteger(Integer i) {
System.out.println(i);
}
And call it with
printInteger(1)
Autoboxing will happen, the cache will be used and you’ll get 2 printed.
Note By default this works from -128 to 128. Which is the default cache, but as you can see in the code you can change the cache size using -XX:AutoBoxCacheMax.
2
solved Java how to redefine fundamental int value [closed]