第五题:十六进制的趣事
public static void main(String[] args) {
System.out.println(Long.toHexString(0x100000000L+0xcafebabe));
System.out.println(0xcafebabe);
System.out.println(ChapterUtil.getFromLong(0xcafebabe));
}
//控制台打印:
//cafebabe
//-889275714
//ffffffffcafebabe
看起来会打印出1cafebabe,但实际上这是long与int的加法,由于java中数值都是有符号的,0xcafebabe是一个int的整数,符号位是1,就代表是负数。long与int相加,会将int提升为long,也就是控制台打印的0xffffffffcafebabe,然后与0x100000000相加,得到最终0xcafebabe的值。
还有就是当int向long拓展时,是以符号填充的。
A widening conversion of a signed integer value to an integral type T simply sign-extends the two’s-complement representation of the integer value to fill the wider format.
从有符号整型值到到整型T的扩展转换,仅仅是对整型值的2的补码进行符号扩展,以填充扩展格式。
第六题:多重转型
public static void main(String[] args) {
System.out.println((int)(char)(byte)-1);
System.out.println(ChapterUtil.getFromInt(-1));
}
//控制台输出:
//65535
//ffffffff
首先,整型-1,被byte强制转换,保留二进制低八位,即 f f ( 16 ) ff_{(16)} ff(16),再强制转化为char。由byte到char,会先转成int,再转为char,java语言规范byte to char。byte 到 int会进行符号位填充,再将int转为char,为 0 x f f f f 0xffff 0xffff,最终转为int,会执行0扩展。结果int的前16位为0,后16位为 0 x f f f f 0xffff 0xffff,转成10进制就是65535.
A widening conversion of a char to an integral type T zero-extends the representation of the char value to fill the wider format.
从char到到整型T的扩展转换,会对该char值进行零扩展,以填充扩展格式。
第七题:互换内容
public static void main(String[] args) {
int x = 1994;//0x7c0
int y = 2001;//0x7d1
x^=y^=x^=y;
System.out.println("x="+x+";y="+y);
x = 1994;//0x7c0
y = 2001;//0x7d1
x ^= y;
y ^= x;
x ^= y;
System.out.println("x="+x+";y="+y);
}
//控制台打印:
//x=0;y=1994
//x=2001;y=1994
x=y=x^=y这个表达式很少有人会这么写,而且还出错了。如果不用临时变量,可以使用以上第二种方法交换值。
第八题:dos equis
public static void main(String[] args) {
char x = 'X';
int i = 0;
System.out.println(true ? x : 0);
System.out.println(false ? i : x);
}
//控制台输出:
//X
//88
看起来都会打印出X,但第二个打印出88,88是X的ASCII码值。
这是由于java语言规范,具体可以查看官网,比较复杂,书上总结三条:
- 如果第二个和第三个操作数具有相同类型,那么它就是条件表达式的类型。
- 如果一个操作数的类型是T,T表示byte、short或char,而另一个操作数是一个int型常量表达式,它的值可以用T表示那么就用T。
- 否则,将对操作数类型运用二进制数字提升,而条件表达式的类型就是第二个和第三个提升后的类型。
true ?x : 0的第二个操作数是char变量,第三个操作数是int常量0,应用第2条,结果可以用char表示就用char;
false ? i : x的第二个操作数是int变量,第三个操作数是char变量,不满足第二条,应用第三条,将char提升到int,最后输出88.