short s = 'a'; // valid Short ss = 'a'; // valid int i = 'a'; // valid Integer ii = 'a'; // invalid
为什么Integer 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有这些不一致和非直观的规则.我错过了什么?
解决方法
Short s = 'a'; // is valid ...
因为char是无符号的16位值(最大值是65,536)而short是有符号的16位值(最大值是32,767),所以有一个缩小的原始转换(char to short),然后是一个装箱转换(short to short) ).
short s = 'a'; // is valid - this is a narrowing primitive conversion (char -> short)
这些是special cases:
In addition,if the expression is a constant expression of
type byte,short,char,or int:
- A narrowing primitive conversion may be used if the type of the
variable is byte,or char,and the value of the constant
expression is representable in the type of the variable.A narrowing primitive conversion followed by a Boxing conversion may
be used if the type of the variable is:
Byte and the value of the constant expression is representable in the
type byte.Short and the value of the constant expression is representable in the
type short.Character and the value of the constant expression is representable in
the type 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;