1. 一个类型转换的例子
public static void main(String[] args) {
int iValue=233;
//强制把一个int类型的值转换成byte类型的值
byte bValue=(byte) iValue;
//将输出-23
System.out.println(bValue);
}
}
上面程序中,将一个233整型强制类型转换为byte类型,从而变成了-23,这就是典型的溢出。
现在就上面的结果进行一下分析:
首先我们来了解一知识下计算机的基础:
所有数字在计算机底层都是以2进制形式存在的 ,原码就是直接将一个10进制数转换成2进制数,但计算机是以补码的形式保存所有的整数。补码的计算规则如下:正数的补码和原码完全相同,负数的补码是其反码加1;反码是对原码按位取反,除了最高位(符号位)保持不变。
现在继续,看看上面的转换问题,下面示范了转换的过程:
上图,就是负数补码和源码转换的示意图!
2.byte类型
java中的byte是8位的有符号数,所能表示的范围是1000 0000 (-128) ~ 0111 1111 (+127)。
public class TestByte { public static void main(String[] args) { byte bval = 127; System.out.println(bval); } } // 输出127如果对byte的赋值大于127,例如 对下面的表达式
byte
number =
200
; // 200是int型,值超过127
byte
num2 = 0xe9; //0xe9是int型,十进制233
将会的得到编译错误,因为编译器会把整数字面量当作int,so it attempts to convert that value to a byte variable.
However, 200 doesn’t fit in the range of a byte is from -127 to 128 so that the compiler complains.
值为127的byte类型的各种输出
public class TestByte { public static void main(String[] args) { byte bval1 = (byte)127; System.out.println("(byte)127输出"); System.out.println("10进制表示:"+ bval1); System.out.println("2进制表示:"+Integer.toBinaryString(bval1)); System.out.println("16进制表示:"+Integer.toHexString(bval1)); System.out.println("16进制格式输出:"+String.format("%02x", bval1)); } }
运行结果:
10进制表示:127 2进制表示:1111111 16进制表示:7f 16进制格式输出:7f
做一点改变,将变量的值改为-4:
byte bval1 = (byte)-4; System.out.println("(byte)-4输出"); System.out.println("10进制表示:"+ bval1); System.out.println("2进制表示:"+Integer.toBinaryString(bval1)); System.out.println("16进制表示:"+Integer.toHexString(bval1)); System.out.println("16进制格式输出:"+String.format("%02x", bval1));运行结果:
(byte)-4输出 10进制表示:-4 2进制表示:1111111111111111111111100 16进制表示:fffffffc 16进制格式输出: fc这里bvall值为-4的时候2进制输出和16进制输出明显要比值为127时长很多,这里输出的实际上是值为-4的int型的变量的输出。
java.lang.Integer.toBinaryString() 方法的声明如下:
public static String toBinaryString(int i)bvall会被转换为int型并赋值给i,-4的的8位二进制补码为:11111100,当转换为int时会进行符号扩展,即为1111111111111111111111100。
bvall为127时上面的过程同样发生,127的的8位二进制补码为:01111111,转为32位int型,00000000000000000000000001111111,方法
toBinaryString()在输出时把前面的0省去了。
用值为153(十六进制为0x99)int字面量给bvall赋值,再看会发生什么:
byte bval1 = (byte)0x99; System.out.println("(byte)结果"); System.out.println("10进制表示:"+ bval1); System.out.println("2进制表示:"+Integer.toBinaryString(bval1)); System.out.println("16进制表示:"+Integer.toHexString(bval1)); System.out.println("16进制格式输出:"+String.format("%02x", bval1));
结果输出:
10进制表示:-103 2进制表示:11111111111111111111111110011001 16进制表示:ffffff99 16进制格式输出:99要想输出153需要下面的操作:
System.out.println(bval1&0xFF);
byte型的 bval1和字面量为0xFF的int型数据进行&运算时
bval1(10011001)会被转换成int型,变为11111111111111111111111110011001,然后执行按位与
11111111 11111111 11111111 10011001 (bval1)
00000000 00000000 00000000 11111111 (0xff ) AND
--------------------------------------------------------
00000000 00000000 00000000 10011001
有了上面的讨论可以执行如下操作:
byte bval1[] = { (byte)0x77, (byte)0x88, (byte) 0x99 }; System.out.println("bval1[]输出"); for(int i=0; i < bval1.length ; i++){ System.out.println("10进制表示:"+ (bval1[i] & 0xff)); System.out.println("16进制表示"+ String.format("0x%02x", bval1[i])); }
3.代表一个整数的字节数组转换为16进制显示
String result = new BigInteger(1, bytes).toString(16);
System.out.println("result:"+ result);
不过,与java.lang.Integer.toHexString()方法类似,结果会省去前面的零,result的输出为0x7f,而不是0x0000007x。
要输出前面的零可以用这样做:
System.out.println(javax.xml.bind.DatatypeConverter.printHexBinary(bytes));
将会输出:000000007F