Java 将整数与==进行比较到底有什么作用?

Java 将整数与==进行比较到底有什么作用?,java,compare,wrapper,Java,Compare,Wrapper,编辑:好吧,好吧,我看错了。我不是在比较整数和整数。注意到了 我的SCJP书上说: 当==用于比较基元时 对于包装器,包装器将是 打开包装,比较将被删除 原始到原始 因此,您可能认为此代码将打印true: 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 == i

编辑:好吧,好吧,我看错了。我不是在比较整数和整数。注意到了

我的SCJP书上说:

当==用于比较基元时 对于包装器,包装器将是 打开包装,比较将被删除 原始到原始

因此,您可能认为此代码将打印
true

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

另外,根据我的书,这应该打印
true

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


给出了什么?

您没有将原语与包装器进行比较。您正在比较两个包装器(引用类型)<代码>=比较对象标识,返回
false
,因为它们是不同的对象

Integer i1 = 1;
Integer i2 = new Integer(1);
System.out.println(i1 == i2);
当您将1指定给
i1
时,该值将被装箱,从而创建一个
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 5.0以来,有自动装箱和拆箱,这意味着包装器可以隐式转换为原语,反之亦然。但是,如果比较两个整数对象,您仍然在比较两个引用,并且没有任何东西会触发自动装箱/取消装箱。如果是这种情况,用J2SE 1.4和更早版本编写的代码将中断。

还要注意,Java cache的较新版本
Integer
s在-128到127范围内(256个值),这意味着:

Integer i1, i2;

i1 = 127;
i2 = 127;
System.out.println(i1 == i2);

i1 = 128;
i2 = 128;
System.out.println(i1 == i2);
将打印
true
false
。(见附件)

道德:为了避免问题,在比较两个对象时,始终使用
.equals()


当您使用
=
将一个已包装的原语与一个原语(例如:
Integer
int
)进行比较时,您可以依赖于取消装箱,但是如果您将两个
Integer
=
进行比较,则会由于@dan04解释的原因而失败。

不,我认为代码打印正确,你回答了自己为什么

当==用于比较基元时 对于包装器,包装器将是 打开包装,比较将被删除 原始到原始

然后比较了两个整数引用,也就是说,它比较了i1和i2的内存地址。你也想要

Integer i1 = 1;
Integer i2 = new Integer(1);
System.out.println(i1.equals(i2));


请注意,您误读了您引用的摘录。摘录特别将其声明限制为以下比较:

int k = 1;
Integer l = new Integer(1);
System.out.println(l == k);

假设我们有一个例子

这个程序代码的输出是什么

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

使用新运算符创建整数对象时,每次都会返回一个新对象。使用“==”运算符比较两个参考变量时,如果两个参考变量引用两个不同的对象,“==”运算符返回false

所以

(a==b)和(e==f)表达式返回false。Integer类缓存-128到127之间的值

使用“==”运算符比较两个整数对象时,如果这两个整数对象是使用自动装箱创建的,则将调用value0f(int i)方法

回答:False-True-False-False

下面是该方法的实现

public static Integer value0f(int i) {
if (i >= IntegerCachedow && i <= IntegerCache.high)
return IntegerCache.cacheli + (-IntegerCachedow));
return new Integer(i);
公共静态整数值0f(int i){

如果(i>=IntegerCachedow&&我明白了,我不确定这本书的这部分是不是写得不好,还是我是个白痴,但我就是搞不清楚它说的是什么原因。我最好的理解是==与!==被区别对待。也许==反映了价值平等(深度平等)但是!=没有。无论如何,书中所说的不会发生IRL。不,本例中的问题在于您正在比较的两种类型。==和!=的行为方式相同。仅此示例就足以让我认为Java是一种病态的玩笑,而不是一种真正的编程语言。@dsimcha-这是一个非常蹩脚的说法。您可以如果比较两个整数指针,C中也会出现同样的问题-只是更显式而已。第二个示例确实打印了
true
。请看这一点很重要,因为只有小整数被插入。-请记住,
integer
只是维护了它使用的内部缓存(对于所述的小值)当执行对
valueOf
的调用时,编译器仍然会生成两行
invokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;
有趣!我从来不会使用==IRL,但这是我们正在讨论的一个非常残酷的考试:)+1是非常相关的一点。我将挑剔并指出它是,尽管Sun JDK附带的1.6源代码显示他们使用上限玩游戏(但它始终至少是127)。不一定是真的,较小的整数值会被缓存,就像调用
integer.valueOf
一样。因此,实际上您是在比较相同的对象。