阅读JAVA 13 SE规范,我在第5章的5.1.7节中找到了。装箱转换有以下保证:
如果装箱的值p是评估常数的结果布尔值,char,short,int或long类型的表达式(第15.28节),以及结果为true,false,范围为'\ u0000'到包含'\ u007f'或-128至127之间的整数,然后令a和b为p的任何两次装箱转换的结果。它总是a == b
我发现在该措辞中遗漏了字节类型的值很奇怪。
例如,在诸如以下的代码中:
Byte b1=(byte)4;
Byte b2=(byte)4;
System.out.println(b1==b2);
我们有一个字节类型的常量表达式,在装箱后,b1和b2的值可能是或不是同一对象。
实际上,没有强制转换的工作方式相同:
Byte b1=4;
这里,在赋值上下文中,我们有一个int类型的常量表达式。因此,根据规格
变窄的原始转换后跟拳击转换可能如果变量的类型为Byte,Short或Character,并且使用常量表达式的值可以在类型字节中表示,简称,或分别为char。
因此表达式将被转换为字节,并且该字节类型的值将被装箱,因此不能保证该值是可插入的。
我的问题是,我在解释规范时是对的,还是缺少某些东西?我查看了规范是否要求对装箱使用Byte.valueOf()方法(对此将得到保证),但事实并非如此。
您正确理解。在同一5.1.7节的结尾(来自https://docs.oracle.com/javase/specs/jls/se13/html/jls-5.html)说:
如果需要分配包装类之一(布尔型,字节,字符型,短型,整型,长型,浮点型或双精度型)的新实例,则装箱转换可能会导致OutOfMemoryError。可用。
Byte
如果应该预先生成,将不会在那里。
另一件事,仍来自同一段:
理想情况下,将原始值装箱将始终产生相同的引用。实际上,使用现有的实现技术可能不可行。上面的规则是一个务实的折衷,要求始终将某些通用值装在无法区分的对象中。该实现可以懒惰地或急切地缓存它们。 对于其他值,该规则不允许对程序员方面的带框值的标识进行任何假设。这允许(但不需要)共享这些参考中的一些或全部。
Integer
描述了拳击承诺,13甚至是7* Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS.
文本是相同的,即使实现随时间而改变。