Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>That's because <code>b += 1.0;</code> is equivalent to <code>b = (int) ((b) + (1.0));</code>. The <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.3" rel="nofollow noreferrer">narrowing primitive conversion (JLS 5.1.3)</a> is hidden in the compound assignment operation.</p> <h3><a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.26.2" rel="nofollow noreferrer">JLS 15.26.2 Compound Assignment Operators</a> (JLS Third Edition):</h3> <blockquote> <p>A compound assignment expression of the form <em>E1 op= E2</em> is equivalent to <em>E1 = (T)((E1) op (E2))</em>, where <em>T</em> is the type of <em>E1</em>, except that <em>E1</em> is evaluated only once.</p> <p>For example, the following code is correct:</p> <pre><code>short x = 3; x += 4.6; </code></pre> <p>and results in <code>x</code> having the value <code>7</code> because it is equivalent to:</p> <pre><code>short x = 3; x = (short)(x + 4.6); </code></pre> </blockquote> <p>This also explains why the following code compiles:</p> <pre><code>byte b = 1; int x = 5; b += x; // compiles fine! </code></pre> <p>But this doesn't:</p> <pre><code>byte b = 1; int x = 5; b = b + x; // DOESN'T COMPILE! </code></pre> <p>You need to explicitly cast in this case:</p> <pre><code>byte b = 1; int x = 5; b = (byte) (b + x); // now it compiles fine! </code></pre> <hr> <p>It's worth noting that the implicit cast in compound assignments is the subject of <strong>Puzzle 9: Tweedledum</strong> from the wonderful book <a href="http://www.javapuzzlers.com/" rel="nofollow noreferrer"><em>Java Puzzlers</em></a>. Here are some excerpt from the book (slightly edited for brevity):</p> <blockquote> <p>Many programmers think that <code>x += i;</code> is simply a shorthand for <code>x = x + i;</code>. This isn't quite true: if the type of the result is wider than that of the variable, the compound assignment operator performs a silent narrowing primitive conversion.</p> <p>To avoid unpleasant surprises, <strong>do not use compound assignment operators on variables of type</strong> <code>byte</code>, <code>short</code>, or <code>char</code>. When using compound assignment operators on variables of type <code>int</code>, ensure that the expression on the right-hand side is not of type <code>long</code>, <code>float</code>, or <code>double</code>. When using compound assignment operators on variables of type <code>float</code>, ensure that the expression on the right-hand side is not of type <code>double</code>. These rules are sufficient to prevent the compiler from generating dangerous narrowing casts.</p> <p>For language designers, it is probably a mistake for compound assignment operators to generate invisible casts; compound assignments where the variable has a narrower type than the result of the computation should probably be illegal.</p> </blockquote> <p>The last paragraph is worth noting: C# is a lot more strict in this regard (see <a href="http://msdn.microsoft.com/en-us/library/aa691316%28VS.71%29.aspx" rel="nofollow noreferrer">C# Language Specification 7.13.2 Compound assignment</a>).</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload