【问题标题】:Java implicit conversionJava 隐式转换
【发布时间】:2015-08-27 17:26:35
【问题描述】:

使用以下代码:

Float a = 1.2;

有一个错误,因为它将小数作为双精度值并且double 是比float 更大的数据类型。

现在,它采用整数作为默认 int 类型。那么,为什么下面的代码没有报错呢?

Byte b = 20;

【问题讨论】:

  • 我不知道你为什么不理解我的问题......你说编译器足够聪明,可以将 20 放入字节中......那么为什么编译器不将 1.2 放入浮点中...... ..我的简单问题是......我读到在java中所有十进制都被视为双精度,而所有整数默认被视为int......那么当我将20分配给一个字节时,为什么它没有给出任何错误...

标签: java jakarta-ee implicit-conversion


【解决方案1】:

编译器足够聪明,可以确定 20 的位表示(int 值)可以放入 byte 中而不会丢失数据。来自Java Language Specification §5.1.3

doublefloat 的缩小原语转换受 IEEE 754 舍入规则 (§4.2.4) 的约束。这种转换可能会丢失精度,但也会丢失范围,从而导致非零 doublefloat 零和有限双精度的 float 无穷大。 double NaN 转换为 float NaN,double infinity 转换为同符号 float infinity。

有符号整数到整数类型 T 的窄化转换只会丢弃除 n 个最低位之外的所有位,其中 n 是用于表示类型 T 的位数。除了可能丢失有关数值,这可能会导致结果值的符号与输入值的符号不同。

另见this thread

【讨论】:

  • 200 的位表示也适合 8 位字节,而不会丢失数据。重要的是目标类型可以表示相同的数值。
  • @Joni - 是的,也不是。因为byte 值是用Java 签名的,所以“适合”实际上意味着“适合7 位”,而不是8 位。 200 的位模式是1100 1000。当将其放入 8 位 byte 值时,它表示值 -56,而不是值 200。这是因为 200 的表示溢出到 byte 的符号位中。关于相同值的表示这一重要的事情,您是绝对正确的。
【解决方案2】:

一般情况下没有隐式缩小转换 - 常量表达式是唯一的例外,它们被 JLS 5.2 明确允许:

此外,如果表达式是 byte、short、char 或 int 类型的常量表达式(第 15.28 节):

* 如果变量的类型是 byte、short 或 char,并且常量表达式的值可以在变量的类型中表示,则可以使用缩小原语转换。

没有提到允许对浮点数进行隐式缩小转换,因此根据一般规则,它们是被禁止的。

【讨论】:

  • +1 用于引用规范中指定 float/double 行为不同于 byte/int 的原因的部分。 (除了缩小之外,在 OP 的特定示例中还丢失了信息,因为 1.2 不能完全用浮点表示。但是,即使该值是 1.0 或其他可以完全表示为 float 的值,编译器也会抱怨。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多