java怪异的赋值规则

时间:2017-04-13 18:02:26

标签: java char integer variable-assignment

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有这些不一致和非直观的规则。我错过了什么?

1 个答案:

答案 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;