促进原始类型
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了解更多详情
带有 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。
我对 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了解更多详情
带有 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 typebyte
.Short
and the value of the constant expression is representable in the typeshort
.Character
and the value of the constant expression is representable in the typechar
.
作为简短回答 - 尝试用 128 替换 12(字节在 -128 到 127 范围内)。 它不会编译,对吧? 这里的结果是编译器知道字节边界。
如需深入解答,您可以深入了解 OpenJDK。