我正在学习Java,并且对编程完全陌生。我试图了解这段代码幕后发生了什么:java中的缩小类型转换
short c = 234;
byte d = (byte) c;
System.out.println(d);
输出结果是-22。有人能解释我幕后发生了什么魔术吗?
我正在学习Java,并且对编程完全陌生。我试图了解这段代码幕后发生了什么:java中的缩小类型转换
short c = 234;
byte d = (byte) c;
System.out.println(d);
输出结果是-22。有人能解释我幕后发生了什么魔术吗?
有人能解释我背后幕后发生了什么魔术吗?
没有魔法可言......检查什么是primitives可以在Java持有
字节的限制:字节的数据类型是一个8位有符号二进制补码整数。 它的最小值为-128,最大值为127(含)。 字节数据类型可以用于节省内存节省实际重要的大型阵列, 。它们也可以用在int的地方,它们的极限有助于澄清你的代码;变量范围受限的事实 可以作为 文档的一种形式。
所以
short c = 234;
将不适合一个字节,这就是为什么你需要cast,负结果值为你转换操作
收缩转换尝试,以适应后得到什么在较窄的表示类型中具有较大表示类型的值。
如果具有较大表示类型的值不会溢出较窄表示类型,没有问题,则值不会更改。
short c = 127;
byte d = (byte) c;
System.out.println(d);
否则,你有一个溢出:
例如以字节,其中最大值为127,这个代码将它留在窄型的边界数值的字节变量127。这是你的实际情况。
例如尝试此代码由1溢出字节类型:
short c = 128;
byte d = (byte) c;
System.out.println(d);
的byte
变量将与127
之后的下一个值来估价。
但它不存在。所以在byte
范围内的JVM循环(-128
到127
)。
它使用的最小值为byte
:-128
。
随着short c = 129;
,它会产生-127
,等...
二进制数234
是11101010
。
虽然这个数字适合8位,但是java中的一个字节是有符号的,所以在java中最大可能的字节值是127.当最重要的(最左边的)位被设置时,这意味着“负数”,所以你得到的数字是负数。
现在,您可能会想知道为什么您获得的号码是-22
而1101010
不是22
。通过研究数字的二进制补码表示可以找到答案。
这里是它的维基百科文章:https://en.wikipedia.org/wiki/Two's_complement
为了扩大从@Mike Nakis答案。字节的值是-128 - 127.通过明确地告诉编译器使用(byte)
进行投射,您要求编译器不关心范围约束并适合它,不管它是什么。
如果你没有使用投编译器将通过打印
incompatible types: possible lossy conversion from short to byte
首先对所有警告你,你必须要了解整数的二进制表示,那么,你有两种基本类型,有不同范围(和位数),当您将值234截断为一个字节时,由于二进制表示形式,234成为负数。 –
,type'short'是16位,'byte'是8位。 – obgnaw
字节已签名。 234 = 256-22。丢掉256个,因为它们都不适合一个字节,而你有-22。 – EJP