In Java, the following is allowed:
char c = 'A' + 1;
Here, c will hold the value 'B'. Above, first the expression is evaluated. So 'A' gets converted to 65, the whole expression evaluates to 66, and then 66 is converted to 'B' since we are storing the value in a char.
The following, however, gives a compile-time error:
char c = 'A';
c = c + 1;
What is the explanation for how Java views the expressions differently? By the way, the following works fine too:
char c = 'A';
c++;
解决方案
It's just the spec. Converting an int to char is a narrowing conversion and 'A' + 1 is a constant expression. A constant expression is (basically) an expression whose result is always the same and can be determined by the compiler. Narrowing conversions are permitted for assignments of byte, short and char when it's a constant expression.
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.
c + 1 is not a constant expression so a compile-time error occurs for the assignment. From looking at the code we can determine that the result should always be the same but the compiler cannot determine it.
One interesting thing we can do is this:
final char a = 'a';
char b = a + 1;
In that case a + 1 is a constant expression because a is final.
The caveat to the constant expression is that the following would also not compile:
char c = 'A' + 99999;
Because the value of 'A' + 99999 is not representable in the type of char.
As for other operators, like ++ that you mention, they have their own specifications. The relevant bit for ++ (and similarly all of the increments and decrements) is:
The type of the postfix increment expression is the type of the variable.
...
Before the addition, binary numeric promotion (§5.6.2) is performed on the value 1 and the value of the variable. If necessary, the sum is narrowed by a narrowing primitive conversion (§5.1.3) ... to the type of the variable before it is stored.
(Presumably a conversion is done for char.) It's also worthwhile to note that += automatically performs narrowing conversion as well. So c += 1; will also compile.