我在Java中有以下方法:
private static short charToShort_1() {
return 's';
}
private static char shortToChar_1() {
return ((short) 15);
}
private static short charToShort_2() {
char ch = 's';
return ch;
}
private static char shortToChar_2() {
short number = 15;
return number;
}
为什么“charToShort_1”和“shortToChar_1”编译成功? 同时,最后两个方法“charToShort_2”和“shortToChar_2”无法编译(因为显式强制转换是必要的)。
答案 0 :(得分:4)
这里:
private static short charToShort_1() {
return 's';
}
's'
是一个常量表达式,此值可在short
中表示。
所以编译器进行隐式转换。
JLS州:
另外,如果表达式是常量表达式(§15.28) 输入byte,short,char或int:
- 如果类型为,则可以使用缩小的基元转换 变量是byte,short或char,以及常量的值 表达式可以在变量的类型中表示。
short
值范围为-32,768
至32,767
(含)
因此,这些边界中的常量表达式char
将产生编译错误:
private static short charToShort_2() {
return '耀'; // 32768 numeric value
}
关于这个不编译的方法:
private static short charToShort_2() {
char ch = 's';
return ch;
}
char ch = 's';
不是常量表达式
您可能使用ch
中无法表示的新char
值重新分配short
(例如由{{1}代表的'耀'
数值)。
因此,编译器希望您将其显式转换为32768
作为转换
可能是一个缩小的原始转换
将其更改为short
变量,您将看到它编译正常:
final
关于从private static short charToShort_2() {
final char ch = 's';
return ch;
}
投射到short
的此方法,编译错误原因与char
完全相同
最后,关于charToShort_2()
:
shortToChar_1()
简化投射可能会给人的印象是,与使用private static char shortToChar_1() {
return ((short) 15);
}
相比,你花费的内存更少:
int
实际上,它并没有改变任何东西,因为在这两种情况下编译器都会使用bipush
JVM指令将private static char shortToChar_1() {
return 15;
}
作为整数值推送到堆栈。
答案 1 :(得分:1)
真正的答案在于Java Language Specification的§5.2(适用于Java 8,但也适用于以前的版本)的声明
此外,如果表达式是byte,short,char或int类型的常量表达式(第15.28节):
如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。
因此,对常量表达式进行特殊处理,因为它们允许一些不允许其他表达式的缩小转换。
答案 2 :(得分:0)
3和4方法是错误的,因为这种转换正在缩小(数据丢失)。您必须明确表明您理解并同意与此转换相关的所有风险。
5.1.3段落 https://docs.oracle.com/javase/specs/jls/se6/html/conversions.html答案 3 :(得分:0)