【问题标题】:Why does *= not give any errors when implicitly casting a float to an int? [duplicate]为什么 *= 在将浮点数隐式转换为 int 时不会给出任何错误? [复制]
【发布时间】:2013-11-25 07:28:38
【问题描述】:

我之前遇到过一种情况,我尝试了以下两段代码:

int score = 100;
score = score * 1.05;

int score = 100;
score *= 1.05;

第一个失败(显然,我试图将浮点数隐式转换为 int)。但第二个工作得很好。编译器没有抱怨,我也没有收到任何运行时错误。为什么第二个有效,而第一个无效?据我所知,x *= y 只是x = x * y 的简写。

【问题讨论】:

  • 类似问题,但对于+=stackoverflow.com/questions/8710619/java-operator 简而言之score *= 1.05 工作正常,因为它与score = (int)(score * 1.05) 相同
  • 你用的是什么编译器?我刚刚在 Visual Studio 2005 上尝试过(是的,我仍在使用它,尤其是在工作中哈哈),它工作得很好。只给了我一个关于从 double 转换为 int 的警告,但仍然运行良好。
  • @Pshemo 啊哈,谢谢!在侧边栏中没有看到任何相关的弹出窗口,所以我以为我是第一个提出这个问题的人。

标签: java casting compilation compiler-errors


【解决方案1】:

复合赋值运算符的行为与其“扩展”版本略有不同。引用JLS, Section 15.26.2

E1 op= E2 形式的复合赋值表达式等价于 E1 = (T) ((E1) op (E2)),其中 T 是 E1 的类型,除了 E1 只计算一次。

它被隐式转换回左侧变量的类型,因此将float转换为int不会出错;它已经隐式转换为 int

= 运算符不会发生这种情况,它由 JLS, Section 5.2, Assignment Conversion 管理:

分配上下文允许使用以下之一:

  • 身份转换(§5.1.1)

  • 一个扩大的基元转换(§5.1.2)

  • 扩大参考转换 (§5.1.5)

  • 装箱转换(第 5.1.7 节)可选地后跟扩大参考转换

  • 拆箱转换(第 5.1.8 节)可选地后跟扩大的原始转换。

它继续讨论允许的可能的缩小转换,但仅适用于常量表达式,并且仅适用于 bytecharshortint 的常量表达式,这两者都不是在这里适用。

【讨论】:

    【解决方案2】:

    第一个

    int score = 100;
    score = score * 1.05;
    

    基本上是在说:

    int score = 100;
    score = (float)(score * 1.05);
    

    这是因为如果你用一个整数来计算一个浮点数,那么你就会得到一个浮点数。这不能被分配给一个整数。

    然而

    int score = 100;
    score *= 1.05;
    

    基本意思是

    int score = 100;
    score = (int)(score * 1.05);
    

    这是因为您没有分配浮点数,计算是在分配时完成的,因此首先转换为 int。

    这对我来说是有意义的。希望对你有帮助

    【讨论】:

      【解决方案3】:

      如果你使用:

      int score=100;
      score *=1.05;
      

      这相当于:

      score=(int)(score*1.05);
      

      这里有更详细的解释:http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.26.2

      E1 op= E2 形式的复合赋值表达式等价于 E1 = (T)((E1) op (E2)),其中 T 是 E1 的类型,除了 E1 只计算一次。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-23
        • 2016-06-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多