2017-07-28 80 views
0

我正在学习Java,并且对编程完全陌生。我试图了解这段代码幕后发生了什么:java中的缩小类型转换

short c = 234; 
byte d = (byte) c; 
System.out.println(d); 

输出结果是-22。有人能解释我幕后发生了什么魔术吗?

+0

首先对所有警告你,你必须要了解整数的二进制表示,那么,你有两种基本类型,有不同范围(和位数),当您将值234截断为一个字节时,由于二进制表示形式,234成为负数。 –

+1

,type'short'是16位,'byte'是8位。 – obgnaw

+0

字节已签名。 234 = 256-22。丢掉256个,因为它们都不适合一个字节,而你有-22。 – EJP

回答

0

有人能解释我背后幕后发生了什么魔术吗?

没有魔法可言......检查什么是primitives可以在Java持有

字节的限制:字节的数据类型是一个8位有符号二进制补码整数。 它的最小值为-128,最大值为127(含)。 字节数据类型可以用于节省内存节省实际重要的大型阵列, 。它们也可以用在int的地方,它们的极限有助于澄清你的代码;变量范围受限的事实 可以作为 文档的一种形式。

所以

short c = 234; 

将不适合一个字节,这就是为什么你需要cast,负结果值为你转换操作

+1

我明白这一点。但我的问题实际上是关于缩小转换中的信息损失。在这种情况下铸造的算法是什么?为什么我们得到-22作为输出为什么不是-30或另一个值?一开始我以为我们应该得到127,因为它是最接近234的字节类型可以容纳的值。 – AmacOS

+0

@AmacOS因为它丢弃了高位,并将剩下的内容解释为8位有符号值。 – EJP

1

收缩转换尝试,以适应后得到什么在较窄的表示类型中具有较大表示类型的值。
如果具有较大表示类型的值不会溢出较窄表示类型,没有问题,则值不会更改。

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循环(-128127)。
它使用的最小值为byte-128

随着short c = 129;,它会产生-127,等...

2

二进制数23411101010‬

虽然这个数字适合8位,但是java中的一个字节是有符号的,所以在java中最大可能的字节值是127.当最重要的(最左边的)位被设置时,这意味着“负数”,所以你得到的数字是负数。

现在,您可能会想知道为什么您获得的号码是-221101010不是22。通过研究数字的二进制补码表示可以找到答案。

这里是它的维基百科文章:https://en.wikipedia.org/wiki/Two's_complement

0

为了扩大从@Mike Nakis答案。字节的值是-128 - 127.通过明确地告诉编译器使用(byte)进行投射,您要求编译器不关心范围约束并适合它,不管它是什么。

如果你没有使用投编译器将通过打印

incompatible types: possible lossy conversion from short to byte