将原语与包装器对象进行比较,其中==行为无法解释

Fr_*_*ien 26 java boxing equality equals

我有一段代码需要我理解:

public static void main(String[] args) {
    Character c = new Character('a');
    Character cy = new Character('a');
    char cx = 'a';

    System.out.println(c == cx);
    System.out.println(cx == cy);
    System.out.println(c == cy);
}
Run Code Online (Sandbox Code Playgroud)

输出:

true
true
false
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么只有第三个陈述失败了.

编辑:这个问题.equals==原始与对象比较的vs 问题不同.

Era*_*ran 45

ccy引用Character该类的不同实例(每次调用构造函数时,都会创建一个新实例),因此比较这些引用将返回false.

另一方面,当您将它们中的任何一个与基元进行比较时cx,它们将被取消装箱char,并且char比较返回true.

如果你使用Character.valueOf('a')而不是new Character('a'),你将在两个调用中获得相同的实例,并且将返回引用比较true(因为如果参数<= 127则valueOf返回缓存Character实例).

  • 遗憾的是,Java的这一部分非常令人困惑(不仅仅是).从Java 5开始,就会出现自动装箱,它试图提供帮助但是使得"=="的行为即使是棘手的.在自动装箱之前,我相信编译器会拒绝前两次比较. (8认同)
  • 请注意,`Character a = Character.valueOf('a')`可以缩短为`Character a ='a'`,即使`valueOf`也会返回非ASCII字符不相等的实例. (6认同)

Sur*_*tta 25

 System.out.println(c == cx);
 System.out.println(cx == cy);
Run Code Online (Sandbox Code Playgroud)

由于一个是原始的而另一个是它的包装类,因此会发生拆箱并进行原始比较(==).

鉴于:

 System.out.println(c == cy);
Run Code Online (Sandbox Code Playgroud)

是一个对象比较.不同的实例正在进行比较,因此==在这种情况下不起作用.