byte,char,int类型转换
问题来源于BufferedInputStream的
public synchronized int read() throws IOException { if (pos >= count) { fill(); if (pos >= count) return -1; } return getBufIfOpen()[pos++] & 0xff; }
getBufIfOpen()[pos++] 是一个byte类型 为什么返回的时候需要&0xff
- 原因应该是,例如 我们获取到的byte是实际的字节内容 如0xff
在byte中代表了-1然后将其转化int类型后 我们实际得到的int为 0xffffffff
而我么希望的到的应该是0x000000ff 即256
通过与0xff与的方式 我们得到了实际需要的4字节的int值 查阅问题的时候 这种情况更多地发生在与char类型转化的过程中
char是2字节的无符号类型 byte和int都是有符号类型java规则
- 如果目标类型比原始类型更长,分为两种情况
- 原始类型为有符号类型,那么直接在在原始对象的高位补该对象的符号位
即 如果是负数则补1 如果是正数则补0 - 原始类型为无符号类型,那么直接在原始对象高位补0,即可视作符号位为正
- 这一机制保证了,在不同类型进行转换的时候 对象转化为更长的目标对象,其数值的一致性
- 问题会出现在有符号类型转化为更长的无符号类型,如byte–>char 当byte为负数时,实际得到的char的值为 65536+byte
- 原始类型为有符号类型,那么直接在在原始对象的高位补该对象的符号位
- 如果目标类型比原始类型更短 则直接截取低位
- 原因应该是,例如 我们获取到的byte是实际的字节内容 如0xff
原始类型 | 原始值 | 目标类型 | 转型后的值 |
---|---|---|---|
byte -1 | 0xff | int | 0xffffff(-1) |
byte 1 | 0x01 | int | 0x00000001(1) |
byte -1 | 0xff | char | 0xffff(65536) |
byte 1 | 0x01 | char | 0x0001(1) |
char 65535 | 0xffff | byte | 0xff(-1) |
char 65535 | 0xffff | int | 0x0000ffff(65535) |
byte b;
int i;
char c;
b = -1;
i = (int) b;
System.out.println(b + " " + Integer.toHexString(b&0xff) + " " + i + " " + Integer.toHexString(i));
b = 1;
i = (int) b;
System.out.println(b + " " + Integer.toHexString(b&0xff) + " " + i + " " + Integer.toHexString(i));
b = 1;
c = (char) b;
System.out.println(b + " " + Integer.toHexString(b&0xff) + " " + Integer.valueOf(c) + " " + Integer.toHexString(c&0xffff));
b = -1;
c = (char) b;
System.out.println(b + " " + Integer.toHexString(b&0xff) + " " + Integer.valueOf(c) + " " + Integer.toHexString(c&0xffff));
c = 0xffff;
b = (byte) c;
System.out.println(b + " " + Integer.toHexString(b&0xff) + " " + Integer.valueOf(c) + " " + Integer.toHexString(c&0xffff));
c = 0xffff;
i = (int) c;
System.out.println(i + " " + Integer.toHexString(i) + " " + Integer.valueOf(c) + " " + Integer.toHexString(c&0xffff));
*************************************
result:
-1 ff -1 ffffffff
1 1 1 1
1 1 1 1
-1 ff 65535 ffff
-1 ff 65535 ffff
65535 ffff 65535 ffff