Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the compiler not give an error for this addition operation? [duplicate]

Tags:

java

I know that the compiler does implicit type conversion for integer literals. For example:

byte b = 2; // implicit type conversion, same as byte b = (byte)2; 

The compiler gives me an error if the range overflows:

byte b = 150; // error, it says cannot convert from int to byte 

The compiler gives the same error when the variable is passed an expression:

byte a = 3; byte b = 5; byte c = 2 + 7; // compiles fine byte d = 1 + b; // error, it says cannot convert from int to byte byte e = a + b; // error, it says cannot convert from int to byte 

I came to the conclusion that the result of an expression that involves variables cannot be guaranteed. The resulting value can be within or outside the byte range so compiler throws off an error.

What puzzles me is that the compiler does not throw an error when I put it like this:

byte a = 127; byte b = 5; byte z = (a+=b); // no error, why ? 

Why does it not give me an error?

like image 547
Flying Gambit Avatar asked Feb 22 '16 06:02

Flying Gambit


People also ask

What causes a compiler error?

Explanation: Option B generates a compiler error: <identifier> expected. The compiler thinks you are trying to create two arrays because there are two array initialisers to the right of the equals, whereas your intention was to create one 3 x 3 two-dimensional array.

What is a compile error in Java?

Compile-time errors occur when there are syntactical issues present in application code, for example, missing semicolons or parentheses, misspelled keywords or usage of undeclared variables. These syntax errors are detected by the Java compiler at compile-time and an error message is displayed on the screen.


1 Answers

While decompiling your code will explain what Java is doing, the reason why it's doing it can be generally found in the language specification. But before we go into that, we have to establish a few important concepts:

  • A literal numeral is always interepreted as an int.

    An integer literal is of type long if it is suffixed with an ASCII letter L or l (ell); otherwise it is of type int (§4.2.1).

  • A byte can only hold an integer value between -128 and 127, inclusive.

  • An attempt to assign a literal that is larger than the type that can hold it will result in a compilation error. This is the first scenario you're encountering.

So we're back to this scenario: why would adding two bytes that are clearly more than what a byte can handle not produce a compilation error?

It won't raise a run-time exception because of overflow.

This is the scenario in which two numbers added together suddenly produce a very small number. Due to the small size of byte's range, it's extremely easy to overflow; for example, adding 1 to 127 would do it, resulting in -128.

The chief reason it's going to wrap around is due to the way Java handles primitive value conversion; in this case, we're talking about a narrowing conversion. That is to say, even though the sum produced is larger than byte, the narrowing conversion will cause information to be discarded to allow the data to fit into a byte, as this conversion never causes a run-time exception.

To break down your scenario step by step:

  • Java adds a = 127 and b = 5 together to produce 132.
  • Java understands that a and b are of type byte, so the result must also be of type byte.
  • The integer result of this is still 132, but at this point, Java will perform a cast to narrow the result to within a byte - effectively giving you (byte)(a += b).
  • Now, both a and z contain the result -124 due to the wrap-around.
like image 186
Makoto Avatar answered Sep 17 '22 21:09

Makoto