Java陷阱:使用==比较原始包装对象,例如Integer
示例
(这一缺陷同样适用于所有的原始包装类,但我们会说明它Integer和int。)
使用Integer对象时,很容易使用==比较值,因为这就是您要使用int值的方式。在某些情况下,这似乎可行:
Integer int1_1 = Integer.valueOf("1"); Integer int1_2 = Integer.valueOf(1); System.out.println("int1_1 == int1_2: " + (int1_1 == int1_2)); //真正 System.out.println("int1_1 equals int1_2: " + int1_1.equals(int1_2)); //真正
在这里,我们创建了两个Integer具有该值的对象,1并将它们进行比较(在这种情况下,我们从a创建一个对象,String从一个int文字创建一个对象。还有其他选择)。此外,我们观察到两种比较方法(==和equals)均产生true。
当我们选择不同的值时,此行为会更改:
Integer int2_1 = Integer.valueOf("1000"); Integer int2_2 = Integer.valueOf(1000); System.out.println("int2_1 == int2_2: " + (int2_1 == int2_2)); //假 System.out.println("int2_1 equals int2_2: " + int2_1.equals(int2_2)); //真正
在这种情况下,只有equals比较才能得出正确的结果。
行为上存在差异的原因是,JVM维护Integer对象高速缓存的范围为-128到127。(可以使用系统属性“java.lang.Integer.IntegerCache.high”或JVM覆盖上限值。参数“-XX:AutoBoxCacheMax=size”)。对于此范围内的值,会返回缓存的值,而不是创建一个新值。Integer.valueOf()
因此,在第一个示例中,Integer.valueOf(1)和Integer.valueOf("1")调用返回相同的缓存Integer实例。相比之下,在第二个示例中,Integer.valueOf(1000)和Integer.valueOf("1000")既创建又返回新Integer对象。
==引用类型的运算符测试引用的相等性(即同一对象)。因此,在第一个示例中int1_1==int1_2是true因为引用相同。在第二个示例中int2_1==int2_2为false,因为引用不同。