原链接:
http://codeway.co/%E5%A6%82%E4%BD%95%E7%BC%96%E7%A8%8B%E5%AE%9E%E7%8E%B0-2-2-5%EF%BC%9F/
Write a program that makes 2 + 2 = 5,看到这个题目,感觉很新颖,第一个答案就是用Java实现的。用上了Java中的整型实例池的概念。以前只看到过实例池导致两个对象的指针相同的问题,即
Integer a = new Integer(2);
Integer b = new Integer(2);
System.out.print(a == b);
a = 2;
b = 2;
System.out.print(a == b);
上面代码中第一处输出的是false,按照Java对象的申请原则来说,new出来的对象地址是不一样的。而第二处因为使用了缓存,因此输出的是true。正是因为JVM在实现的时候,默认生成了一些Integer对象的实例,当需要的实例是池子中已经存在的数值时,直接返回已经生成的对象的引用,不必新构造对象。这样可以极大减少实例数目和程序运行性能。
而这个题目是将池子中的对象的内容进行了修改,最终使得取回的实例的值发生了改变。这样其实很危险的,如果在正式运行程序的业务代码之前,做这个修改,那么整个程序的运行逻辑将产生混乱。
import java.lang.reflect.Field;
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);
}
}
上面是具体的代码,最终输出的结果为5,作者给出的解释为:
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.
利用缓存的读写接口,将4这个实例的缓存对象的指针改为指向5的实例对象了,这样,当应用程序取出4时,实际上返回的是5的引用,打印出来的也就是5了。
分享到:
相关推荐
在Java编程中,将`List<Object>`转换为Json格式是一种常见的需求,特别是在处理服务器与客户端之间的数据交换或者存储数据到数据库之前。这个过程涉及到对象序列化和JSON库的使用。以下是一个详细的步骤和知识点讲解...
.Select(x => ConvertXmlElementToT(x)) .ToList(); ``` 其中,`ConvertXmlElementToT`是一个辅助方法,负责将 XElement 对象转换为 T 类型的对象。 5. **第二种实现方法**:使用`XmlSerializer`。`XmlSerializer...
在Java编程中,将一个`List<Integer>`转换成以逗号分隔的`String`字符串是一种常见的需求,尤其是在处理数据展示或格式化输出时。Java 8引入了新的特性和方法,使得这种转换变得更加简洁和高效。下面我们将深入探讨...
数字转中文<br>128 自动计算金额<br>129 JSP页面打印中使用WebBrowser控件<br>130 <select...>不刷新页面添加新的类别<br>131 鼠标滚动缩放图片<br>132 根据输入的表名生成输入数据表格<br>133 JSP表格输出到Excel...
而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键.<br><br>2.将一个 1M -10M 的文件,逆序存储到另一个文件,就是前一个文件的最后一个 <br>字符存到新文件的第...
43<br><br>0061 树的实现 44<br><br>3.2 排序 48<br><br>0062 如何实现选择排序算法 48<br><br>0063 如何实现冒泡排序算法 49<br><br>0064 如何实现快速排序算法 50<br><br>0065 如何实现插入排序算法 ...
发生异常时,异常周围信息(抛出对象本身类型)-------------异常处理程序<BR><BR>12.5一个异常处理的简单实例:除数为0<BR><BR>需求:使用一个小应用程序,完成两数相除的计算<BR><BR><BR><BR><BR><BR><BR><BR><BR>...
142<br>4.7.2 实例实现 142<br>4.8 设置桌面快捷方式和活动桌面 145<br>4.8.1 实现原理 145<br>4.8.2 实例实现 146<br><br>第5章 基本网络编程实例 150<br>5.1 点对点文件传输 150<br>5.2 端口扫描程序...
bool existsEvenNumber = numbers.Exists(n => n % 2 == 0); // 返回 true ``` 对比`Contains`和`Exists`,我们可以得出以下几点区别: 1. **性能**:对于简单的查找,`Contains`通常更快,因为它直接使用哈希表。...
高级I/O 273<br>12.1 引言 273<br>12.2 非阻塞I/O 273<br>12.3 记录锁 275<br>12.3.1 历史 276<br>12.3.2 fcntl记录锁 276<br>12.3.3 锁的隐含继承和释放 280<br>12.3.4 4.3+BSD的实现 281<br>12.3.5 建议性锁和强制...
高级I/O 273<br>12.1 引言 273<br>12.2 非阻塞I/O 273<br>12.3 记录锁 275<br>12.3.1 历史 276<br>12.3.2 fcntl记录锁 276<br>12.3.3 锁的隐含继承和释放 280<br>12.3.4 4.3+BSD的实现 281<br>12.3.5 建议性锁和强制...
142<br>4.7.2 实例实现 142<br>4.8 设置桌面快捷方式和活动桌面 145<br>4.8.1 实现原理 145<br>4.8.2 实例实现 146<br><br>第5章 基本网络编程实例 150<br>5.1 点对点文件传输 150<br>5.2 端口扫描程序...
高级I/O 273<br>12.1 引言 273<br>12.2 非阻塞I/O 273<br>12.3 记录锁 275<br>12.3.1 历史 276<br>12.3.2 fcntl记录锁 276<br>12.3.3 锁的隐含继承和释放 280<br>12.3.4 4.3+BSD的实现 281<br>12.3.5 建议性锁和强制...
142<br>4.7.2 实例实现 142<br>4.8 设置桌面快捷方式和活动桌面 145<br>4.8.1 实现原理 145<br>4.8.2 实例实现 146<br><br>第5章 基本网络编程实例 150<br>5.1 点对点文件传输 150<br>5.2 端口扫描程序...
高级I/O 273<br>12.1 引言 273<br>12.2 非阻塞I/O 273<br>12.3 记录锁 275<br>12.3.1 历史 276<br>12.3.2 fcntl记录锁 276<br>12.3.3 锁的隐含继承和释放 280<br>12.3.4 4.3+BSD的实现 281<br>12.3.5 建议性锁和强制...
高级I/O 273<br>12.1 引言 273<br>12.2 非阻塞I/O 273<br>12.3 记录锁 275<br>12.3.1 历史 276<br>12.3.2 fcntl记录锁 276<br>12.3.3 锁的隐含继承和释放 280<br>12.3.4 4.3+BSD的实现 281<br>12.3.5 建议性锁和强制...
List<T>实现了多个接口,包括IList<T>、ICollection<T>、IEnumerable<T>、IList、ICollection和IEnumerable,从而提供了丰富的功能和方法。 泛型类的优势主要体现在提高了程序的类型安全性和性能。因为List<T>是强...
142<br>4.7.2 实例实现 142<br>4.8 设置桌面快捷方式和活动桌面 145<br>4.8.1 实现原理 145<br>4.8.2 实例实现 146<br><br>第5章 基本网络编程实例 150<br>5.1 点对点文件传输 150<br>5.2 端口扫描程序...
if (b >= 1000 && b <= 10000 && 8 * i < 100 && 9 * i >= 100) output(b, i); } ``` 这里首先定义了一个循环变量 `i`,用于表示题目中的 `??`,并初始化为 10(因为 `??` 表示两位数)。然后计算 `809 * ?? + 1` ...
<br>2、熟悉VC编程、编译和调试环境;<br>内容及步骤:<br>编写一个类Complex,定义复数的加法、减法、乘法和除法运算,要求在编写该类时重载这些运算操作符,并重载I/O操作符,以便输入和输出复数;<br>实验报告要求...