Java - 为什么char会被隐式地转换为字节(和简短)原语,什么时候不应该?

str*_*lle 7 java byte type-conversion char implicit-cast

编译器的某些功能让我感到困惑(使用Eclipse的Oracle JDK 1.7).

所以我有这本书说char原语需要明确地转换为short和byte,这一切都有意义,因为数据类型的允许范围不重叠.

换句话说,下面的代码可以工作(但如果没有显式类型转换,则无法工作):

char c = '&';  
byte b = (byte)c;
short s = (short)c;
Run Code Online (Sandbox Code Playgroud)

正确打印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
Run Code Online (Sandbox Code Playgroud)

现在我肯定会理解以下内容(也适用):

byte bt = (byte)'&';
System.out.println(bt); // Correctly displays number 38 on the console
Run Code Online (Sandbox Code Playgroud)

但是对于字节(和短)"潜行转换"这个无编译器警告字符对我来说似乎不对.

有人可以解释,为什么允许这样做?

原因可能在于对'<char>'自身的解释,因此它实际上并没有达到char原始状态,而是作为数字(八进制或十六进制等)值处理?

Den*_*ret 6

基本上,赋值转换规范指定了

此外,如果表达式是byte,short,char或int类型的常量表达式(第15.28节):

如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示.

'&'的确是"byte,short,char或int类型的常量表达式".


das*_*ght 6

这称为常量的编译时缩小.它在Java语言规范的5.2节中描述:

常量的编译时缩小意味着代码如下:

byte theAnswer = 42;
Run Code Online (Sandbox Code Playgroud)

被允许.如果没有缩小,整数文字42具有int类型的事实将意味着需要转换为字节.

字符文字也是如此:如果它的值适合a byte,则不需要转换; 如果值不合适,则必须进行强制转换,否则会出现编译错误.

例如,这不会编译:

byte bc = '\uff12'; // Does not compile without a cast
Run Code Online (Sandbox Code Playgroud)

但是编译很好:

byte bc = (byte)'\uff12';
Run Code Online (Sandbox Code Playgroud)