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

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

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类的不同实例(每次调用构造函数时,都会创建一个新实例),因此比较这些引用将返回false

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

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

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

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

鉴于:

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

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

Charcter类不是单例,所以在调用构造函数时总会创建一个新对象,而新对象引用它们各自的引用。所以(c == cy)给你错误

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

然而,前两个比较给出的原因只是部分明确: char值肯定用于检索预先存储的Character实例,但我不知道预定义的Character对象是如何映射到此前的存储的实例

我希望,它的工作方式类似于“==” – String对象的比较:如果在编译时,其中一个比较实例是预先存储的Character那么编译器会插入一个调用equals()替换“==” -comparision