将原始对象与具有无法解释的 == 行为的包装对象进行比较

Comparing primitive to wrapper object with == behaviour unexplained

我有一段代码需要理解:

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

输出:

true
true
false

我无法理解为什么只有第三个语句失败。

编辑:这个问题不同于 .equals vs == 问题,因为这个问题是关于原始对象与对象的比较。

ccy 引用 Character class 的不同实例(每次调用构造函数时,都会创建一个新实例),因此比较这些参考文献 returns false.

另一方面,当您将它们中的任何一个与原始 cx 进行比较时,它们被拆箱为 char,并且 char 比较 returns 为真。

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

 System.out.println(c == cx);
 System.out.println(cx == cy);

由于一个是原始的,另一个是它的包装器 class,unboxing happens 和原始比较发生 (==)。

鉴于:

 System.out.println(c == cy);

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

Charcter class 不是单例,因此在调用构造函数时总是会创建一个新对象,并且新对象会引用它们各自的 references.So (c == cy) 给你 false

很明显为什么最后的比较给出 false:两个 Character 都用 new 显式初始化,因此是不同的对象

为什么前两个比较给出 true,但是,只是部分清楚:char 值肯定用于检索预存储的 Character 实例,但我不不知道预定义的 Character 对象是如何映射到这个预存储的实例

不过,我希望它像“==”一样工作 - String 对象的比较:如果在编译时比较的实例之一是预存储的 Character 那么编译器插入对 equals() 的调用以替换“==”-比较