当比较Integer对象和常量值时,Java是将值装箱还是取消对Integer对象的装箱?
根据我所读到的,"==“是一种引用比较,因此,假设Java是执行对象之间引用比较的常量,这是合乎逻辑的。然而,下面的测试代码似乎给出了相互矛盾的结果。
Integer v1 = 1000;
Integer v2 = 1000;
boolean b1 = v1 == 1000; //True.
boolean b2 = v1 == v2; //False. Proof that 1000 boxes to new object and is not fetched from cache.那么,使用==进行对象与常值比较是如何在Java中工作的呢?在这种情况下,操作符是否按值进行比较?
发布于 2020-03-04 06:44:57
您所称的“常量值”是一个int文本,因此它的类型是int。
如果相等运算符的操作数都是数值类型,或者一个是数值类型,另一个是可转换为数字类型(§5.1.8),则对操作数执行二进制数值提升。
在v1 == 1000测试中,1000是数字类型,v1可以转换为数字类型,因此执行二进制数字提升。
JLS 5.6.2 (二进制数字升级)说:
如果任何操作数是引用类型的,则受取消装箱转换的限制。
因此,Integer操作数-- v1 --被解封到int中,并对两个int进行比较。因此,比较的结果是true。
当您比较两种引用类型-- v1 == v2 --没有取消装箱的位置时,只比较引用,如用JLS 15.21.3编写的那样。
如果相等运算符的操作数都是引用类型或空类型,则操作是对象相等。
由于1000太大,不能被Integer缓存缓存,所以b1和b2没有引用同一个实例,因此比较的结果是false。
发布于 2020-03-04 06:52:09
整数池与字符串池相同,但如果-128到127中的整数对象缓存值,那么当您尝试将此 range 中的值分配给包装器对象时,装箱操作将调用方法,然后将分配给池中已经存在的对象的引用。
但是,如果将此Integer.valueOf range之外的值分配给包装器引用类型,则将为该值创建一个新的Integer对象。因此,比较在此范围之外具有值的Integer对象的引用将给出false。
所以在你的情况下
Integer v1 = 1000;
Integer v2 = 1000;
boolean b1 = v1 == 1000; //True.
boolean b2 = v1 == v2; // out of range so it will false but if you use 127 instead of 1000 then it will true.查看文档这里
https://stackoverflow.com/questions/60520358
复制相似问题