将原语与包装器对象进行比较,其中==行为无法解释
我有一段代码需要我理解:
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 ==
问题不同,因为这与原始与对象的比较有关。
c
和cy
引用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