有关 Java 中原始数据类型的隐式类型转换的查询

问题描述 投票:0回答:1

我一直在学习 Java 中的类型转换,并且发生了这种情况。

首先,我给一个整型变量一个很大的值(比字节数据类型的范围更大的数字)。 接下来,我创建了一个字节变量并尝试对第一个变量的值进行类型转换。 显然,这应该会引发错误,因为字节的范围比第一个变量的值短。我在 JSHELL 中做到了这一点。

Screenshot of my problem

我想知道为什么 java 没有给我一个错误,而是给出了一个完全不同的数字。我没有看到任何字节环绕,因为结果值要大得多。

java implicit-conversion
1个回答
4
投票

首先,让我解释一下为什么将 300 转换为字节时会得到 44。为此,我需要首先解释内存中的整数表示。 Java 与大多数编程语言一样,使用二进制补码表示有符号整数。简而言之,每个数字都由固定数量的二进制数字(位)

n
表示,其中第一个表示符号,其他
n-1
表示大小。对于正数,那些
n-1
位只是二进制数。

Java 整数类型之间的主要区别在于

n
int
n = 32
位上工作,而
byte
使用
n = 8
位。这意味着您的数字 300 在内存中表示为
0000'0000'0000'0000'0000'0001'0010'1100
。现在,您想要将此数字转换为仅使用 8 位的表示形式,但您可以清楚地看到您至少需要 10 位(9 表示大小,1 表示符号)。因此,您将需要丢失一些信息。 Java没有考虑这个问题(事实上,它也没有办法这样做),只是简单地复制最右边的8位,得到
0010'1100
。将其转换为以 10 为基数确实会得到 44。

请注意,如果您了解二进制,则在从

int
byte
的转换中,您在 256 处丢失了 1。这可能会让您更直观地了解为什么 300 - 44 = 256。

其次,让我们谈谈 Java 不会给你错误的事实。首先请注意,以下代码不会编译,因为 int 可以保存比

byte
更大的值:
int myfirstnumber = 100;
byte mysecondnumber = myfirstnumber;  // error: incompatible types: possible lossy conversion from int to byte

编译器拒绝让你在没有你确认的情况下进行缩小转换;它认为这样的语法太容易出错。然而,您有时可能想要进行这样的转换。在这种情况下,你必须表明这确实是你的意图:

int myfirstnumber = 100; byte mysecondnumber = (byte)myfirstnumber;

在这种情况下,编译器认为你知道自己在做什么,正如 
@old-dog-programmer

指出的那样。现在,如果您不想在转换时丢失数据,您应该自己验证是否存在溢出: int myfirstnumber = 100; byte mysecondnumber = 0; if(Byte.MIN_VALUE <= myfirstnumber && myfirstnumber <= Byte.MAX_VALUE) { mysecondnumber = (byte)myfirstnumber; } else { // handle the error }

© www.soinside.com 2019 - 2024. All rights reserved.