促进原始类型

Promotion of primitive types

我对 Java 中原始类型的提升有疑问。正如我们在下面的例子中看到的,其中一个方法由于类型不匹配的错误而没有编译。每个方法 returns 相同的值但类型不同。

原始版本 long 方法工作正常,而包装器版本 class Long 失败。这是因为 return 语句中的 int 文字将首先提升为更广泛的原始类型(例如 long),然后再提升为相应的包装器 class Integer 等等。由于 Integer 不是 Long 的子 class,编译器会给出错误。

但为什么 wrapper class Byte 的版本没有任何错误?此时编译器究竟做了什么?

long getPrimitiveLong() {
    return 12; // valid
}

Long getWrapperLong() {
    return 12; // Error: type mismatch
}

Byte getWrapperByte() {
    return 12; // valid
}

这是因为 Java 允许 1 次转换或自动装箱,而不是更多。

Java 可以做到所有这些:

int i = 5;
double d = i; // int to double
long l = i; // int to long
long l = d; // double to long

或自动装箱:

Integer i = 5; // int to Integer
Double d = 5.0; // double to Double
Long l = 5L; // long to Long

转换两次,比如 int 到 Double,给 Java 带来了困难。

编译器默认将 12 之类的数字视为 int,这就是错误的原因

要解决此问题,您可以对 byte 使用转换并将 L 放在 long 变量的值之后。

阅读以下内容post了解更多详情

http://javaseeeedu.blogspot.com/2015/12/casting-part-1.html

带有 Byte 的版本通过一些编译器魔法工作。

不像 long 可以用 L 后缀构造的数字文字,例如12L,没有 byte 文字这样的东西。这就是为什么 Java 编译器将适合一个字节的数字文字视为 byte 文字。因此,上一个示例中的 12 被视为 byte.

类型的常量

Java Language Specification 在第 5.2 节中提供了此转换的描述:

A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:

  • Byte and the value of the constant expression is representable in the type byte.
  • Short and the value of the constant expression is representable in the type short.
  • Character and the value of the constant expression is representable in the type char.

作为简短回答 - 尝试用 128 替换 12(字节在 -128 到 127 范围内)。 它不会编译,对吧? 这里的结果是编译器知道字节边界。

如需深入解答,您可以深入了解 OpenJDK。