Java 不会同时装箱和转换原始类型

Java doesn't box and convert primitive types at the same time

我知道 java(c?) 可以对类型进行装箱和拆箱,并在必要时在基本类型之间进行转换,但为什么它不想同时进行这两种操作。

例如,如果我要这样做:

ArrayList<Byte> bytes = new ArrayList<>();
bytes.add(8);

Javac 会恐慌并告诉我 Collection.add(Byte) 不适用,但如果我使用 ArrayList<Integer> 而不是问题。 如果我这样做 byte aByte = 8; bytes.add(aByte); 它也可以正常编译。

这是为什么,有充分的理由吗?

之所以会发生这种情况,是因为如果您这样做 bytes.add(8),8 将作为 int 处理。所以抛出以下错误:

The method add(Byte) in the type ArrayList < Byte> is not applicable for the arguments (int)

如果您想将 8 直接添加到您的 ArrayList 中,您必须将 8 转换为一个字节

bytes.add((byte)8);

无法在必要时将 8 处理为 byte,而在其他情况下将其处理为 int

想想下面的例子:

private static void test() {
  Object o = 8;
}

现在,如果您想要 8 作为 byteint,则不会指定。 所以数字总是作为整数处理而不是作为字节处理。所以 JVM 可以将 8 装箱到正确的包装器 class。 o.getClass() 在这个例子中是 java.lang.Integer

同样的事情也适用于小数,例如2.3 定义为 double 如果你想 2.3 作为浮点数你必须写 2.3f.