gpt4 book ai didi

java - Java中的隐式转换如何工作?

转载 作者:行者123 更新时间:2023-12-01 06:54:55 26 4
gpt4 key购买 nike

我知道在Java中,整数默认是int,所以如果我写这样的话

byte byteValue = 2;
Java自动将文字值 2 (默认为int)转换为字节。
如果我写同样的东西
byte byteValue = 4/2;
RHS被评估为一个int值,并隐式转换为一个字节。
但是,在以下两种情况下为什么不进行隐式转换?
int n1 = 4;
byte value = n1/2;
或者在这个
byte n1 = 4;
byte value = n1/2;
我知道这两个示例的RHS都被评估为int。但是Java为什么不像前两种情况那样将其隐式转换为字节,仅当有文字时才隐式转换为较小的数据类型?

最佳答案

说明
让我们看一下您的代码和一些修改后的示例:

// Example 1
byte byteValue = 2;

// Example 2
byte byteValue = 4/2;

// Example 3
byte byteValue = 2000;

// Example 4
byte byteValue = 500/2;

// Example 5
int n1 = 4;
byte byteValue = n1/2;

无损转换
您将获得示例3,示例4和示例5的提及的编译时错误。
首先,示例1至4的简单数学运算是在编译时执行的。因此,Java将在编译时计算 500 / 2,并使用 byte byteValue = 250;基本上替换该代码。
Java中字节的有效值为 -128127。因此,超出该范围的任何值都不能仅视为 byte,而需要进行显式转换。因此,示例1和示例2通过了。

有损缩小转换
为了理解其余部分为什么失败,我们必须研究Java语言规范(JLS),更具体地说是 5.1.3. Narrowing Primitive Conversion5.2. Assignment Contexts一章。
它说从 intbyte的转换(如果它不在 byte的范围内)是 缩小了原始转换,并且它 可能会丢失信息(出于明显的原因)。继续说明转换是如何完成的:

A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.


从第二章开始,如果值是 常数表达式,则允许进行窄转换的 分配

In addition, if the expression is a constant expression (§15.29) of type byte, short, char, or int:

A narrowing primitive conversion may be used if the variable is of type byte, short, or char, and the value of the constant expression is representable in the type of the variable.


简而言之,必须向Java明确声明可能会丢失信息(因为值超出范围)的缩小转换。 Java不仅会在不强制您的情况下为您完成任务。这是通过 Actor 阵容完成的。
所以举个例子
byte byteValue = (byte) (500 / 2);
产生值 -6

常数表达
您的最后一个示例非常有趣:
int n1 = 4;
byte byteValue = n1/2;
尽管不超出范围,但Java仍将其视为有损缩小转换。为什么会这样?
好吧,Java无法保证 n1在执行 n1/2之前的第二秒内没有更改。因此,它必须考虑所有代码,以查看是否有人偷偷地访问了 n1并对其进行了更改。 Java在编译时不进行这种分析。
因此,如果您可以告诉Java n1保持 4且实际上永远不会改变,那么它将可以编译。在这种特定情况下,将其设置为 final就足够了。所以用
final int n1 = 4;
byte byteValue = n1/2;
它实际上将进行编译,因为Java知道 n1保留为 4并且无法再更改。因此,它可以在编译时将 n1/2计算为 2,并将代码替换为基本上在范围内的 byte byteValue = 2;
因此,如前面在 5.2. Assignment Contexts中所述,您将 n1 / 2设为 常数表达式
您可以检查详细信息,以便在 15.29. Constant Expressions中具有常量表达式。基本上,所有简单的事情都可以轻松地就地计算,而无需任何方法调用或其他花哨的东西。

关于java - Java中的隐式转换如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62965817/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com