Integer i = 127;
Integer j = 127;
System.out.println(i == j);
System.out.println(i.equals(j));
Integer i1 = 128;
Integer j1 = 128;
System.out.println(i1 == j1);
System.out.println(i1.equals(j1));
我不明白为什么它不打印“真实,真实,真实,真实”。请给出答案?
答案 0 :(得分:29)
使用==
时,您要比较对象实例是否相等。
前两个实例相同的原因是您使用自动装箱创建Integers
(而不是调用new Integer(127)
),而Java Language Specification §5.1.7要求Integers
缓存-128到127之间。
实现可以缓存比这更多的值,但不是必需的;显然你正在使用的JVM不会缓存128.这就是Sun Java 6的情况。
答案 1 :(得分:9)
只是为了添加所有其他正确答案,请查看source code,以便完全了解@mmyers所说的内容:
584 /**
585 * Returns an {@code Integer} instance representing the specified
586 * {@code int} value. If a new {@code Integer} instance is not
587 * required, this method should generally be used in preference to
588 * the constructor {@link #Integer(int)}, as this method is likely
589 * to yield significantly better space and time performance by
590 * caching frequently requested values.
591 *
592 * @param i an {@code int} value.
593 * @return an {@code Integer} instance representing {@code i}.
594 * @since 1.5
595 */
596 public static Integer valueOf(int i) {
597 final int offset = 128;
598 if (i >= -128 && i <= 127) { // must cache
599 return IntegerCache.cache[i + offset];
600 }
601 return new Integer(i);
602 }
答案 2 :(得分:5)
整数是一个类。如果键入new Integer(),则创建一个新对象。所以i,j,i1和j1都是不同的对象。如果你使用==它只对同一个对象是真的。对于小于128的整数,JVM始终使用相同的对象,因此输出为true。
答案 3 :(得分:4)
不,不应该:
Integer i1 = 128;
Integer j1 = 128;
Autoboxing导致在您正在使用的Java实现中创建两个不同的Integer对象。
如果整数值在-128到127范围内,则JLS声明将使用相同的Integer对象;见JLS 1.5.7。但是,JLS确实不要求i1
和i2
必须具有该范围之外的不同值。事实上,JLS中的以下讨论说明了这一点:
理想情况下,装箱给定的原始值p将始终产生相同的参考。实际上,使用现有的实现技术可能不可行。上述规则是一种务实的妥协。上面的最后一个条款要求将某些常见值装入无法区分的对象中。实施可能会懒惰地或急切地缓存这些。
对于其他值,此公式不允许对程序员的盒装值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。
这确保了在大多数情况下,行为将是所需的行为,而不会造成过度的性能损失,尤其是在小型设备上。例如,较少内存限制的实现可以缓存所有字符和短路,以及-32K - + 32K范围内的整数和长整数。