【问题标题】:Java breaks strong typing! Who can explain it? [duplicate]Java 打破了强类型!谁能解释一下? [复制]
【发布时间】:2011-12-12 10:02:08
【问题描述】:

可能重复:
Varying behavior for possible loss of precision

我在编译时发现 Java 强类型检查不一致。 请看以下代码:

int sum = 0;
sum = 1; //is is OK
sum = 0.56786; //compile error because of precision loss, and strong typing
sum = sum + 2; //it is OK
sum += 2; //it is OK
sum = sum + 0.56787; //compile error again because of automatic conversion into double, and possible precision loss
sum += 0.56787; //this line is does the same thing as the previous line, but it does not give us a compile error, and javac does not complain about precision loss etc.

谁能给我解释一下?它是已知的错误,还是期望的行为? C++ 给出警告,C# 给出编译错误。

Java 会破坏强类型吗? 您可以将 += 替换为 -= 或 *= - 编译器可以接受所有内容。

【问题讨论】:

  • 奇怪的是你将浮点数存储在 int 变量中
  • @KarelFrajtak 没有修饰符的十进制数(如 df)是双精度数,而不是浮点数。此外,我认为您可能错过了重点..
  • Java 显然在这里犯了一个错误。当允许无声演员时,他们应该更精确。演员阵容的原因在于另一个错误的决定。整数类型操作的规范是一团糟。
  • @irreputable:浮点类型的规则更糟糕。如果两者都允许,哪个更值得警告:float f=1.0/10.0;double d=1.0f/10.0f;?一种好的语言应该能够定义 == 运算符,因此它在所有编译的情况下都表现为等价关系(x==y 编译和 y==z 编译的事实并不意味着 x==z 必须编译,但如果所有三个都编译,两个返回 true,第三个也应该),但是 Java 在很多方面都失败了。

标签: java strong-typing


【解决方案1】:

此行为由语言定义(因此可以)。来自the JLS

15.26.2 复合赋值运算符

E1 op= E2 形式的复合赋值表达式是等价的 到 E1 = (T)((E1) op (E2)),其中 T 是 E1 的类型,除了 E1 只评估一次。例如下面的代码是正确的:

short x = 3;
x += 4.6;

并导致 x 的值为 7,因为它等价于:

short x = 3;
x = (short)(x + 4.6);

【讨论】:

  • 这是一个经常被忽视的东西,我们倾向于认为 += 只是一个更短的版本,但它确实有其他含义。要记住的好提示。
  • 不行。爪哇错了。该示例没有理由编译。
  • @irreputable - 好吧,这是语言设计者需要考虑的事情;编译器符合规范。
  • 这是问题的(不太重要的)部分。
【解决方案2】:

它编译是因为编译器正在转换

sum += 0.56787;

sum = (int)(sum + 0.56787);

【讨论】:

  • 您能否提供一个文档链接来解释此行为。我认为正常行为是自动转换为精度更高的类型。
  • 强制转换是在添加之后执行的,而不是之前。查看最佳答案。
【解决方案3】:

这与强类型无关,仅与隐式转换的不同规则有关。

您在这里看到两个不同的运算符。在第一种情况下,您有一个简单的赋值运算符“=”,它不允许将 double 分配给 int。在第二种情况下,您有复合赋值运算符“+=”,它允许通过首先将double 转换为int,将double 添加到int

【讨论】:

  • 是的,但这与 C++ 或 C# 中的工作方式非常不同。
  • 当然,这些是来自 JLS 的特定于 Java 的规则。
  • 嗯?根据定义,隐式转换规则的选择完全取决于强类型与弱类型。
  • 是的,但这个问题与强类型和弱类型无关。这是关于认识到有两个不同的运算符具有两组不同的隐式转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-23
  • 2015-07-06
  • 2017-12-03
  • 2019-08-26
  • 1970-01-01
  • 1970-01-01
  • 2017-04-07
相关资源
最近更新 更多