应该非常清楚的是,缓存的性能受到不可接受的影响 - 每次创建整数时都会进行额外的 if 语句和内存查找。仅此一点就掩盖了任何其他原因以及这条线上的其他痛苦。
就“正确”地回答==而言,OP在正确性假设上是错误的。整数确实通过一般Java社区对正确性的期望,当然还有规范对正确性的定义来正确响应==。也就是说,如果两个引用指向同一对象,则它们是 。如果两个引用指向不同的对象,即使它们具有相同的内容,它们也不会指向不同的对象。因此,将评估结果为 应该不足为奇。==
==
new Integer(5) == new Integer(5)
false
更有趣的问题是,为什么每次都需要创建一个唯一的实例?即为什么不允许缓存?答案是和呼叫。缓存会错误地导致线程在不应该同步时彼此同步。new Object();
new Object();
wait(...)
notify(...)
new Object()
如果不是这样,那么Java实现完全可以用单例缓存s。new Object()
这应该可以解释为什么必须完成7次才能创建7个唯一对象,每个对象都包含值5(因为扩展)。new Integer(5)
Integer
Integer
Object
次要的,不太重要的东西:这个不错的方案中的一个问题来自自动装箱和自动开箱功能。没有该功能,您将无法进行比较,例如.为了启用这些,Java 取消了对象的框(并且不会将基元框化)。因此转换为:(而不是 。new Integer(5) == 5
new Integer(5) == 5
new Integer(5).intValue() == 5
new Integer(5) == new Integer(5)
最后要了解的一件事是 自动装箱 不是由 完成的。它是在内部通过调用 来完成的。n
new Integer(n)
Integer.valueOf(n)
如果您认为自己理解并希望测试自己,请预测以下程序的输出:
public class Foo {
public static void main (String[] args) {
System.out.println(Integer.valueOf(5000) == Integer.valueOf(5000));
System.out.println(Integer.valueOf(5000) == new Integer(5000));
System.out.println(Integer.valueOf(5000) == 5000);
System.out.println(new Integer(5000) == Integer.valueOf(5000));
System.out.println(new Integer(5000) == new Integer(5000));
System.out.println(new Integer(5000) == 5000);
System.out.println(5000 == Integer.valueOf(5000));
System.out.println(5000 == new Integer(5000));
System.out.println(5000 == 5000);
System.out.println("=====");
System.out.println(Integer.valueOf(5) == Integer.valueOf(5));
System.out.println(Integer.valueOf(5) == new Integer(5));
System.out.println(Integer.valueOf(5) == 5);
System.out.println(new Integer(5) == Integer.valueOf(5));
System.out.println(new Integer(5) == new Integer(5));
System.out.println(new Integer(5) == 5);
System.out.println(5 == Integer.valueOf(5));
System.out.println(5 == new Integer(5));
System.out.println(5 == 5);
System.out.println("=====");
test(5000, 5000);
test(5, 5);
}
public static void test (Integer a, Integer b) {
System.out.println(a == b);
}
}
对于额外的信用,如果所有==
.equals(...)
更新:感谢用户@sactiw的评论:“缓存的默认范围是-128到127,java 1.6以后,您可以通过从命令行传递-XX:AutoBoxCacheMax=来重置上限值>= 127”