30

Why does:

public class Addition { 
  public static void main() { 
    int a = 0; 
    double b = 1.0; 
    a = a + b;
    System.out.println(a); 
  }
}

not compile but:

public class Addition { 
  public static void main() { 
    int a = 0; 
    double b = 1.0; 
    a += b; 
    System.out.println(a); 
  }
}

compiles.

Radiodef
  • 37,180
  • 14
  • 90
  • 125
rawnd
  • 375
  • 4
  • 8

4 Answers4

32

In Java += operator has an implicit cast to the left hand type. This goes for all composed operators.

DefLog
  • 1,009
  • 7
  • 13
23

int = int + double is essentially

int = double + double

and you cannot do that without casting...

The int += double forces the result to an int while the other one requires casting.

So a = (int)(a + b);

should compile.

Edit: as requested in the comments... here is a link to more reading (not the easiest read, but the most correct info): http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.2

LoicAG
  • 603
  • 3
  • 19
TofuBeer
  • 60,850
  • 18
  • 118
  • 163
  • could you provide some link on that for further reading? Thanks – hhafez Mar 04 '09 at 00:32
  • i think the "deep" reason is because it's disallowed to assign while narrowing: byte = int is disallowed and int = double too. would one do a simple byte a; a += 2; and fail to compile, people would throw shoes at java. but i would still have liked extra rules that make it work without that cast :( – Johannes Schaub - litb Mar 04 '09 at 01:20
  • I'm not certain there is a deep reason, but the Java language specification explicitly defines the implicit cast: http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5304 – DefLog Mar 04 '09 at 06:08
4

double + int returns double, so double = double + int is legitimate, see JLS 5.1.2 Widening Primitive Conversion on the other hand int = double + int is "Narrowing Primitive Conversion" and requires explicit cast

devdimi
  • 2,432
  • 19
  • 18
0

As everyone already stated, the += has an implicit cast. To help illustrate that, I'm going to use an app I wrote a while back that is perfect for these types of questions. It's an online disassembler so you can check out the actual bytecode that's being produced: http://javabytes.herokuapp.com/

And a table of their meanings: http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

So let's take a look at the bytecode from some simple Java code:

int i = 5;
long j = 8;
i += j;

Disassembled code. My comments will have a // in front.

   Code:
        0: iconst_5  //load int 5 onto stack
        1: istore_0  //store int value into variable 0 (we called it i)
        2: ldc2_w #2; //long 8l
                     //load long 8 value onto stack.  Note the long 8l above
                     //is not my comment but how the disassembled code displays 
                     //the value long 8 being used with the ldc2_w instruction
        5: lstore_1  //store long value into variable 1 (we called it j)
        6: iload_0   //load int value from variable 0
        7: i2l       //convert int into a long.  At this point we have 5 long
        8: lload_1   //load value from variable 1
        9: ladd      //add the two values together.  We are adding two longs
                     //so it's no problem
        10: l2i      //THIS IS THE MAGIC.  This converts the sum back to an int
       11: istore_0  //store in variable 0 (we called it i)
Jonnyman9
  • 36
  • 2
  • 3