我有一个关于在Java中推广原始类型的问题。正如我们在下面的示例中所看到的,由于类型不匹配的错误,其中一个方法无法编译。每个方法返回相同的值,但是使用不同的类型。
当包装类int
的版本失败时,原始return
方法的版本可以正常工作。这是因为long
语句中的Integer
字面值将首先提升为更宽的基本类型(例如Integer
),然后提升为相应的包装类Long
,依此类推。由于Byte
不是long getPrimitiveLong() {
return 12; // valid
}
Long getWrapperLong() {
return 12; // Error: type mismatch
}
Byte getWrapperByte() {
return 12; // valid
}
的子类,编译器会给出错误。
但是为什么包装类ALL
的版本没有任何错误?编译器究竟做了什么?
CREATE PARTITION SCHEME myRangePS1
AS PARTITION myRangePF1
ALL TO (test1fg) ;
GO
答案 0 :(得分:6)
带有Byte
的版本通过一些编译器魔法工作。
与long
数字文字不同,后者可以使用L
后缀构建,例如12L
,没有byte
字面值。这就是为什么Java编译器将符合字节的数字文字视为byte
文字的原因。因此,您上一个示例中的12
被视为byte
类型的常量。
Java Language Specification在第5.2节中提供了此转换的说明:
可以使用缩小的基元转换,然后进行装箱转换 如果变量的类型是:
Byte
,常量表达式的值可在byte
类型中表示。Short
,常量表达式的值可在short
类型中表示。Character
,常量表达式的值可在char
类型中表示。
答案 1 :(得分:3)
这是因为Java允许1次转换或Autoboxing,而不是更多。
Java可以完成所有这些:
int i = 5;
double d = i; // int to double
long l = i; // int to long
long l = d; // double to long
或autobox:
Integer i = 5; // int to Integer
Double d = 5.0; // double to Double
Long l = 5L; // long to Long
转换两次,比如说int为Double,给Java带来了困难。
答案 2 :(得分:0)
要解决此问题,您可以使用强制转换为byte并将L放在long变量的值之后。
阅读以下帖子了解更多详情
答案 3 :(得分:0)
作为一个简短的答案 - 尝试用128替换12(字节在-128到127的范围内)。 它不会编译,对吧? 这里的结果是编译器知道字节边界。
对于深入的回答,您可以深入了解OpenJDK。