java 为什么在 return 类型的方法中可以使用 char to short

java why char to short is possible in method return type

我在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" 无法编译(因为需要显式转换)。

3 和 4 方法是错误的,因为此转换正在缩小(丢失数据)。您必须明确表明您了解并同意与此转换相关的所有风险。

5.1.3段 https://docs.oracle.com/javase/specs/jls/se6/html/conversions.html

答案很简单,因为char在java中是无符号数据类型,而short是有符号数据类型,所以在java中没有隐式转换

根据Oracle

char to short is a narrowing primitive conversion

真正的答案在于 Java Language Specification 的 §5.2 中的声明(对于 Java 8,但也适用于以前的版本)

In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:

A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.

所以常量表达式被特殊对待,因为它们允许一些其他表达式不允许的缩小转换。

这里:

private static short charToShort_1() {
    return 's';
}

's' 是一个常量表达式,这个值可以在 short 中表示。 所以编译器会进行隐式转换。

JLS 状态:

In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:

  • A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.

short 值范围是 -32,76832,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 中无法表示(例如 '耀'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);
}

转换为 short 可能会给人一种印象,即与使用 int 相比,您占用的内存更少:

private static char shortToChar_1() {
    return 15;
}

事实上,它不会改变任何东西,因为在这两种情况下,编译器将使用 bipush JVM 指令将 byte 作为整数值压入堆栈。