编译器的某些功能令我费解(Oracle JDK 1.7使用Eclipse)。
所以我有一本书说char原语需要显式转换为短字节,这一切都是有意义的,因为数据类型的允许范围不重叠。
换句话说,下面的代码可以工作(但是没有显式类型转换就无法工作):
char c = '&';
byte b = (byte)c;
short s = (short)c;打印b或s正确地显示数字38,这是Unicode中(&)的数字等效。
,这就引出了我的实际问题。为什么下面的工作也是如此呢?
byte bc = '&';
short sc = '&';
System.out.println(bc); // Correctly displays number 38 on the console
System.out.println(sc); // Correctly displays number 38 on the console现在,我肯定会理解以下几点(这也是可行的):
byte bt = (byte)'&';
System.out.println(bt); // Correctly displays number 38 on the console但是这种没有编译器警告的字节(和短)“秘密转换”对我来说似乎不对。
有人能解释一下,为什么允许这样做?
原因是否在于对'<char>'本身的解释,这样它就不会真正进入char原语状态,而是被处理为一个数值(八进制或十六进制等)值?
发布于 2013-06-12 10:51:31
基本上,转让转换规范指定
此外,如果表达式是字节、短、字符或int类型的常量表达式(§15.28): 如果变量的类型是字节、短或字符,并且常量表达式的值可以在变量的类型中表示,则可以使用收缩基元转换。
您的'&'正是“字节、短、字符或int类型的常量表达式”。
发布于 2013-06-12 10:52:23
这被称为常数的编译时收缩。Java语言规范第5.2节对此进行了描述:
常数的编译时缩小意味着代码(如: 字节theAnswer = 42; 是允许的。如果不进行缩小,整数文本42具有int类型这一事实意味着需要对字节进行强制转换。
字符文本也是如此:如果其值适合于byte,则不需要转换;如果该值不适合,则必须进行强制转换,否则将得到编译错误。
例如,这将不会编译:
byte bc = '\uff12'; // Does not compile without a cast但这是很好的汇编:
byte bc = (byte)'\uff12';发布于 2013-06-12 10:45:36
为什么下面的工作也是如此?
因为'&'是一个常量表达式,其值适合于byte。
JLS 14.4.2
如果声明器具有初始化表达式,则计算表达式,并将其值分配给变量。
JLS 5.2
赋值转换是在将表达式的值分配给变量时发生的:表达式的类型必须转换为变量的类型。 …… 此外,如果表达式是字节、短、字符或int类型的常量表达式(§15.28):
https://stackoverflow.com/questions/17063436
复制相似问题