short s = 'a'; // valid
Short ss = 'a'; // valid
int i = 'a'; // valid
Integer ii = 'a'; // invalid
为什么整数ii =' a'无效,但是int i =' a'有效?为什么短ss =' a'有效,但整数ii =' a'无效?
另一个问题:
byte b;
final short s = 1;
final Short ss = 1;
final int i =1;
final Integer ii = i;
final long L = 1;
final Long LL =1L;
b = s; // valid
b = ss; // invalid
b = i; // valid
b = ii; // invalid
b = L; // invalid
b = LL; // invalid
为什么b = L;无效,而b = s;有效吗?
请不要说这一切都是因为JLS这么说。我想知道为什么JLS有这些不一致和非直观的规则。我错过了什么?
答案 0 :(得分:5)
所以,行:
Short s = 'a'; // is valid ...
因为 char 是无符号的16位值(最大值是65,536)而 short 是带符号的16位值(最大值是32,767),所以有一个缩小原始转换(char为short),然后进行拳击转换(short to Short)。
short s = 'a'; // is valid - this is a narrowing primitive conversion (char -> short)
这些是special cases:
另外,如果表达式是常量表达式 输入 byte , short , char 或 int :
- 如果类型为,则可以使用缩小的基元转换 变量是 byte , short 或 char ,以及常量的值 表达式可以在变量的类型中表示。
缩小的原始转换后跟拳击转换可能 如果变量的类型是:
,则使用
字节,常量表达式的值可以表示为 输入 byte 。
短,常量表达式的值可表示为 输入 short 。
Character 和常量表达式的值可表示 类型 char 。
让我们进入下一个例子:
Integer ii = 'a'; // is invalid - not a special case according to Oracle docs
int i = 'a'; // is valid - widening primitive conversion (char -> int) is allowed
还有一个案例来自你的问题:
byte b;
final long L = 1;
b = L // error - incompatible types
为什么 b = L 行无效?因为它不是上述特殊情况,我们可能会在演员表中丢失信息,这就是为什么你必须明确地执行它:
b = (byte) L; // is valid - narrowing primitive conversion (long -> byte)
另外,请查看非常有用的table。
在JLS文档中有很多关于所有这些规则的信息,您不必担心所有这些规则。关于你的上一个问题,我能说的是,如果没有隐式缩小转换,任何整数文字都需要在接下来的情况下使用强制转换:
// Cast is permitted, but not required - profit!
byte b = (byte) 100;
short s = (short) 100;
由于我们可以将其更改为:
byte b = 100;
short s = 100;