将Integers与==进行比较究竟做了什么?
编辑:好的,好的,我误读了。 我不是将int与Integer进行比较。 正好指出。
我的SCJP书说:
当==用于将基元与包装器进行比较时,包装器将被解包,并且比较将是原始的。
所以你认为这段代码会打印出来:
Integer i1 = 1; //if this were int it'd be correct and behave as the book says. Integer i2 = new Integer(1); System.out.println(i1 == i2);
但它打印false
。
另外,根据我的书,这应该打印为true
:
Integer i1 = 1000; //it does print `true` with i1 = 1000, but not i1 = 1, and one of the answers explained why. Integer i2 = 1000; System.out.println(i1 != i2);
不。 这是false
。
是什么赋予了?
Integer i1 = 1; Integer i2 = new Integer(1); System.out.println(i1 == i2);
为i1
分配1时,该值被装箱,创建一个Integer
对象。 然后比较比较两个对象引用。 引用不相等,因此比较失败。
Integer i1 = 100; Integer i2 = 100; System.out.println(i1 != i2);
因为这些是使用编译时常量初始化的,所以编译器可以并且实际执行它们并使两者都指向相同的Integer
对象。
(注意,我将值从1000更改为100.正如@NullUserException指出的那样,只有小整数被实现。)
这是一个非常有趣的测试。 看看你是否可以解决这个问题。 为什么第一个程序打印为true
,但第二个程序为false
? 利用您对拳击和编译时间分析的了解,您应该能够解决这个问题:
// Prints "true". int i1 = 1; Integer i2 = new Integer(i1); System.out.println(i1 == i2); // Prints "false". int i1 = 0; Integer i2 = new Integer(i1); i1 += 1; System.out.println(i1 == i2);
如果您了解上述内容,请尝试预测此程序打印的内容:
int i1 = 0; i1 += 1; Integer i2 = new Integer(i1); System.out.println(i1 == i2);
(你猜后, 跑吧看看! )
另请注意,较新版本的Java缓存Integer
在-128到127范围内(256个值),这意味着:
Integer i1, i2; i1 = 127; i2 = 127; System.out.println(i1 == i2); i1 = 128; i2 = 128; System.out.println(i1 == i2);
会打印出false
。 (在ideone上看到它)
道德:为了避免问题,在比较两个对象时总是使用.equals()
。
当您使用==
将包装的基元与基元(例如: Integer
与int
)进行比较时,您可以依赖取消装箱,但如果您要将两个Integer
与==
进行比较,这将因为@ dan04解释的原因而失败。
您没有将基元与包装器进行比较。 您正在比较两个包装器(引用类型)。 ==
比较对象标识,它返回false
因为它们是不同的对象。
不,我不认为代码打印是真的,你回答了自己的确切原因。
当==用于将基元与包装器进行比较时,包装器将被解包,并且比较将是原始的。
然后你继续比较两个整数引用 – 也就是说,它比较了i1和i2的内存地址。 你也想要
Integer i1 = 1; Integer i2 = new Integer(1); System.out.println(i1.equals(i2));
要么
int i1 = 1; Integer i2 = new Integer(1); System.out.println(i1 == i2);
请注意,您误读了所引用的摘录。 摘录明确地将其声明限制为这样的比较:
int k = 1; Integer l = new Integer(1); System.out.println(l == k);
从Java 5.0开始,有自动装箱和拆箱,这意味着包装器可以隐式转换为基元,反之亦然。 但是,如果比较两个Integer对象,则仍在比较两个引用,并且没有任何内容会触发自动装箱/取消装箱。 如果是这种情况,用J2SE 1.4和之前编写的代码就会破坏。
假设我们有一个例子
这个程序代码的输出是什么?
public class autoboxing { public static void main(String a args) { Integer a = new Integer(127); Integer b = new Integer(127); Integer c = 127; Integer d = 127; Integer e = new Integer(200); Integer f = new Integer(200); Integer g = 200; Integer h = 200; System.out.println((a == b) + ' " + (c =-- d) + " " + (e==f)+ " "+ (g == h));
。
使用new运算符创建Integer对象时,每次都返回一个新对象。 当您使用“==”运算符比较两个引用变量时,如果两个引用变量引用两个不同的对象,则“==”运算符返回false。
所以,
(a == b)和(e == f)表达式返回false。 整数类缓存介于-128到127之间的值。
当您使用“==”运算符比较两个Integer对象时,如果使用自动装箱创建这两个整数对象,则将调用value0f(int i)方法。
答案:错误真假
以下是该方法的实现
public static Integer value0f(int i) { if (i >= IntegerCachedow && i <= IntegerCache.high) return IntegerCache.cacheli + (-IntegerCachedow)); return new Integer(i);
从上面的实现,下面是结论
-
如果两个Integer对象值介于-128到127之间,则此方法返回相同的值。 所以(c == d)返回true。
-
如果两个Integer对象值超出-128到127的范围,则此方法返回不同的新Integer对象。 所以,(g == h)返回false
有关此方法的更多详细信息,请访问: https : //stackoverflow.com/questions/20897020/why-integer-class-caching-values-in-the-range-128-to-127
- UUID缩短
- 是否有在微码中运行Java的CPU?
- 无法使用JDK1.8.0_92编译JSP文件
- 如何使用JSF实现JQuery确认对话框
- 将XMLGregorianCalendar转换为java.sql.Timestamp
- 正则表达式匹配不是特定子字符串的东西
- 智能卡终端删除:SCARD_E_NO_SERVICE CardException
- Java,Spark和Cassandra java.lang.ClassCastException:com.datastax.driver.core.DefaultResultSetFuture无法转换为阴影
- 无法从命令行运行jar文件:“no main manifest attribute”