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?

4
  • 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 Commented May 9, 2017 at 6:30
  • Use javap -v Converter.class to see whats happening in the second case. Pay special attention to the d2i and i2b instructions :) Commented May 9, 2017 at 6:34
  • so can I say that shorthand operator suppresses the lossy conversion error and simply does what input it has? Commented May 9, 2017 at 6: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. Commented May 9, 2017 at 6:53

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

Comments

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

1 Comment

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).

2 Comments

@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.
I agree, by the way, your example should use b = 1 instead of b = 10 to show the lossy conversion ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.