http://sighingnow.github.io/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/2_plus_2_equals_5.html
实现2+2=5
Java、Python都采取了常量实例池优化的技术,也就是预先生成-128~127之间的所有常量对象,每次创建这个范围内的对象时直接返回其引用即可。在一般的程序中,这个范围内的常量使用很频繁,因此,这个常量池可以取得非常好的效果。
然而,Java、Python都会允许程序员做一些很Hacker的事情,例如,利用常量池优化使得2+2=5。
public class Main {
public static void main(String[] args) throws Exception {
Class cache = Integer.class.getDeclaredClasses()[0];
Field c = cache.getDeclaredField("cache");
c.setAccessible(true);
Integer[] array = (Integer[]) c.get(cache);
array[132] = array[133];
System.out.printf("%d",2 + 2);
}
}
对于这段代码的解释是这样的:
You need to change it even deeper than you can typically access. Note that this is designed for Java 6 with no funky parameters passed in on the JVM that would otherwise change the IntegerCache.
Deep within the Integer class is a Flyweight of Integers. This is an array of Integers from −128 to +127. cache[132] is the spot where 4 would normally be. Set it to 5.
Since you're already using reflection, you could easily make this independent of the cache size (which does depend on runtime flags after all): Field f = Integer.class.getDeclaredField("value"); f.setAccessible(true); f.set(4, 5) Could be made even more reliable by just grabbing the first non-static field - any reasonable implementation will only have a single field after all.
实现2+2=5
Java、Python都采取了常量实例池优化的技术,也就是预先生成-128~127之间的所有常量对象,每次创建这个范围内的对象时直接返回其引用即可。在一般的程序中,这个范围内的常量使用很频繁,因此,这个常量池可以取得非常好的效果。
然而,Java、Python都会允许程序员做一些很Hacker的事情,例如,利用常量池优化使得2+2=5。
public class Main {
public static void main(String[] args) throws Exception {
Class cache = Integer.class.getDeclaredClasses()[0];
Field c = cache.getDeclaredField("cache");
c.setAccessible(true);
Integer[] array = (Integer[]) c.get(cache);
array[132] = array[133];
System.out.printf("%d",2 + 2);
}
}
对于这段代码的解释是这样的:
You need to change it even deeper than you can typically access. Note that this is designed for Java 6 with no funky parameters passed in on the JVM that would otherwise change the IntegerCache.
Deep within the Integer class is a Flyweight of Integers. This is an array of Integers from −128 to +127. cache[132] is the spot where 4 would normally be. Set it to 5.
Since you're already using reflection, you could easily make this independent of the cache size (which does depend on runtime flags after all): Field f = Integer.class.getDeclaredField("value"); f.setAccessible(true); f.set(4, 5) Could be made even more reliable by just grabbing the first non-static field - any reasonable implementation will only have a single field after all.