关于自动装箱和对象相等/标识的Java问题
为什么关于自动装箱和对象相等/标识的Java问题,java,integer,autoboxing,Java,Integer,Autoboxing,为什么b1==b2为假而c1==c2为真?您想要的答案是您可以在这里找到答案: 在第六个答案中 编辑:很抱歉,答案不准确。关键是==在与Integer一起使用时比较引用,而不是值。但是用int“==”表示等于。Read Java在-128到127的范围内为整数s使用池 这意味着如果您创建一个整数,且整数i=42的值介于-128和128之间,则不会创建新对象,但会返回池中相应的对象。这就是为什么c1确实与c2相同的原因 (我假设您知道,当应用于对象时,=比较引用,而不是值)。因为整数代表一些低数值
b1==b2
为假而c1==c2
为真?您想要的答案是您可以在这里找到答案:
在第六个答案中
编辑:很抱歉,答案不准确。关键是==在与Integer一起使用时比较引用,而不是值。但是用int“==”表示等于。Read
Java在-128到127的范围内为整数s使用池
这意味着如果您创建一个整数,且整数i=42如果代码>的值介于-128和128之间,则不会创建新对象,但会返回池中相应的对象。这就是为什么c1
确实与c2
相同的原因
(我假设您知道,当应用于对象时,=
比较引用,而不是值)。因为整数代表一些低数值,例如枚举,所以始终存在相同的实例。但是更高的数字会创建Integer和operator==的新实例,比较它们的引用已经给出了正确的答案。但再加上我的两分钱:
public class Main {
/**
* @param args the command line arguments */
public static void main(String[] args) {
// TODO code application logic here
int a1 = 1000, a2 = 1000;
System.out.println(a1==a2);//=>true
Integer b1 = 1000, b2 = 1000;
System.out.println(b1 == b2);//=>false
Integer c1 = 100, c2 = 100;
System.out.println(c1 == c2);//=>true
}
}
这是一个糟糕的代码。对象应该通过构造函数或工厂方法初始化为对象。例如
Integer b1 = 1000, b2 = 1000;
或
此代码
// always use a new object
Integer b2 = new Integer(1000);
另一方面,这意味着Integer是一个原语,而事实并非如此。实际上,你所看到的是一条通往成功的捷径
Integer b1 = 1000, b2 = 1000;
Integer只将对象从-127汇集到127,因此在本例中它将创建两个新对象。所以尽管1000=1000,b1!=b2。这就是我讨厌自动装箱的主要原因。公共静态整数值(int I){
Integer b1 = Integer.valueOf(1000), b2 = Integer.valueOf(1000);
最终整数偏移=128;
如果(i>=-128&&i如果在使用“==”运算符进行相等性检查时自动取消装箱也起作用,则可以编写:
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
这需要实现对==的重写,以便null==someLong为false,而特殊情况null==null为true。相反,我们必须使用equal()并测试null
Long notNullSafeLong1 = new Long(11L)
Long notNullSafeLong2 = new Long(22L)
if ( notNullSafeLong1 == notNullSafeLong2) {
do suff
这比第一个例子要详细一点-如果自动拆箱对“==”操作符有效。非常感谢Felix Kling。我理解了这个代码,但它不能解释为什么a1==a2。如果我没有弄错的话,问题是关于b1==b2
和c1==c2
。a1==a2,因为它们是原始的“int”类型,而不是整型对象类型范围在-128和127之间。对于源代码中的引用,第一个答案的范围也是正确的!>这是糟糕的代码。对象应该通过构造函数或工厂方法初始化为对象。
这不完全正确。当您创建字符串实例时,最佳做法是s写String str=“str”
@Rob确实如此。而且,这个答案很老了,我不确定我今天会写同样的答案
Long notNullSafeLong1 = new Long(11L)
Long notNullSafeLong2 = new Long(22L)
if ( notNullSafeLong1 == notNullSafeLong2) {
do suff
Long notNullSafeLong1 = new Long(11L)
Long notNullSafeLong2 = new Long(22L)
if ( (notNullSafeLong1 == null && notNullSafeLong2 == null) ||
(notNullSafeLong1 != null && notNullSafeLong2 != null &
notNullSafeLong1.equals(notNullSafeLong2)) {
do suff