The following code:
public class Example006 {public static void main (string[] args) {System.out.println ("(byte)-1 =" + (byte)-1);//System. Out.println ("(char)-1 =" + (char)-1);//System.out.println ("(Char) ((byte)-1) =" + (char) ((byte)-1)); System.out.println ("(int) ((char) ((byte)-1) =" + (int) ((char) ((byte)-1));}}
Output Result:
(byte)-1 = 1 (int) (char) ((byte)-1) = 65535
cause Analysis:
the behavior of the program closely depends on the transformation of the symbolic expansion behavior. Java uses a 2-based complement of binary operations, so the value of the int type-1 of all 32 bits are set (complement: Positive with the original code, negative sign bit unchanged, the other bits are reversed, so-1 of all 32 bits are 1). The transformation from int to byte is simple, and it performs a narrowing of the primitive type conversions directly to all the bits except the lower 8 bits all cut off. This leaves a byte with a 8-bit position, which still represents-1 (8 of 1).
the transition from byte to char is a little trickier because byte is a signed type, and Char is an unsigned type. When converting an integer type to an integer type with a wider width, it is usually possible to maintain its numeric value, but it is not possible to represent a negative byte value as a char. Therefore, the conversion from byte to char is not considered a widening of the primitive type conversion, but rather a widening and narrowing of the original type of transformation: byte is converted to int, and this int is converted to char.
There is a simple rule that describes the symbol extension behavior when converting from a narrower integer to a wider integer: If the initial numeric type is signed, the symbol extension is executed, and if it is a char, whatever type it will be converted to, it executes
0 extensions.
Because Byte is a signed type, a symbol extension occurs when a byte value of 1 is converted to char. The 16 bits of the char value as a result are all set, so it equals 2^16-1, or 65535. The transformation from char to int is also a widening of the primitive type conversions, so this rule tells us that it will perform 0 extensions instead of symbolic extensions. As a result, the int value is also 65535, which is the result of the program printing.
If you are transforming a char value C into a wider-width type, and you do not want to have a symbolic extension, consider using a bitmask, even if it is not required, to explicitly express your intent:
int i = c & 0xFFFF;
Or, write a comment describing the behavior of the transformation:
int i = C; Symbol extensions are not performed
If you are transforming a char value C into a wider integer, and you want to have a symbol extension, first convert char to a short, which has the same width as char, but it is signed. After giving this subtle code, you should also write a comment for it:
int i = (short) C; Transformation will cause symbol expansion
If you are transforming a byte value B into a char, and you do not want to have a symbolic extension, then you must use a bitmask to limit it. This is a common practice, so no comment is required:
char C = (char) (b & 0xff);
More resources:
1, about the Java symbol Extension problem explanation: http://bbs.csdn.net/topics/310238373
2, complement at least introduce: http://baike.so.com/doc/4026477.html
This article from "Winger" blog, declined reprint!
Problems caused by multiple strong turns of "Java doubts"