以下代码打印“true,true,false,true”。它不应该是“真实,真实,真实,真实”吗?

时间:2010-03-23 12:57:13

标签: java

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));

我不明白为什么它不打印“真实,真实,真实,真实”。请给出答案?

4 个答案:

答案 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确实要求i1i2必须具有该范围之外的不同值。事实上,JLS中的以下讨论说明了这一点:

  

理想情况下,装箱给定的原始值p将始终产生相同的参考。实际上,使用现有的实现技术可能不可行。上述规则是一种务实的妥协。上面的最后一个条款要求将某些常见值装入无法区分的对象中。实施可能会懒惰地或急切地缓存这些。

     

对于其他值,此公式不允许对程序员的盒装值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。

     

这确保了在大多数情况下,行为将是所需的行为,而不会造成过度的性能损失,尤其是在小型设备上。例如,较少内存限制的实现可以缓存所有字符和短路,以及-32K - + 32K范围内的整数和长整数。