4

Consider the following piece of code:

class Converter {
    public static void main(String args[]) {
        byte num = 1;
        num = num * 2.5;
        System.out.println("Result is: " + num);
    }
}

The compiler throws the following error:

error: incompatible types: possible lossy conversion from double to the byte at line 1

If I change the second line of the main() method and I use the *= shorthand operator:

class Converter {
    public static void main(String args[]) {
        byte num = 1;
        num *= 2.5;
        System.out.println("Result is: " + num);
    }
}

The code compiles and runs successfully with the output:

Result is: 2

Why the *= shorthand operator is behaving differently from the full expression num = num * 2.5?

Karl Knechtel
  • 51,161
  • 7
  • 77
  • 117
  • 2
    why do you think it would´nt happen? It basicly does `x = (byte)(x * y)`. So it does have an implicit type casting. I mean the first error is already warning you, that a type conversion will make you lose the preccision when casting from `double` to `byte` – SomeJavaGuy May 09 '17 at 06:30
  • Use `javap -v Converter.class` to see whats happening in the second case. Pay special attention to the d2i and i2b instructions :) – TheLostMind May 09 '17 at 06:34
  • so can I say that shorthand operator suppresses the lossy conversion error and simply does what input it has? – Kamalakar Thakare May 09 '17 at 06:35
  • No. You can't. You can say what @SomeJavaGuy said, virtually quoting the JLS, that the compound assignment (not "shorthand") operator includes a cast, a cast that you omitted in the non-compound example. – Lew Bloch May 09 '17 at 06:53

3 Answers3

11

From the JLS compound assigment operator documentation, you can see the following example :

For example, the following code is correct:

short x = 3;
x += 4.6;

and results in x having the value 7 because it is equivalent to:

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

It simply auto cast the result by default.

PS : In this other answer I tried to explain the reason you need to cast an operation like the following using the JLS

short x = 3;
x = x + 1; //Won't compile

It is realativly new so I am open to suggestion there.

Community
  • 1
  • 1
AxelH
  • 13,322
  • 2
  • 21
  • 50
2

As already said by AxelH it is a compound assignement but I would like to uderline this:

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

That means that by definition it is casting the result. For example:

byte b = 1;
b *= 2.3;
System.out.println(b); // prints 2

From your comment:

So can I say that shorthand operator suppresses the lossy conversion error and simply does what input it has?

No, you can't. It's not suppressing any error because there is no error in casting (in this context).

granmirupa
  • 2,709
  • 14
  • 27
  • @AxelH I think that your answer is good. I also upvoted. But I just wanted to underline why that was happening. Reading now the comment of the OP leaded me to better explain that it's not suppressing any error. Instead it is casting. That is different. – granmirupa May 09 '17 at 07:04
  • I agree, by the way, your example should use `b = 1` instead of `b = 10` to show the lossy conversion ;) – AxelH May 09 '17 at 07:06
2

According to java language specification "15.26.2. Compound Assignment Operators".

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

And you can saw bytecode of your example after compilation(check instruction 3-10).

   3: i2d //convert an int into a double
   4: ldc2_w          #2                  // double 2.5d
   7: dmul //multiply two doubles
   8: d2i //    convert a double to an int
   9: i2b //convert an int into a byte
  10: istore_1 //store int value into variable 1

enter image description here