Why is "int i = 2147483647 + 1;" OK, but "byte b = 127 + 1;" is not compilable?

JavaByteInt

Java Problem Overview


Why is int i = 2147483647 + 1; OK, but byte b = 127 + 1; is not compilable?

Java Solutions


Solution 1 - Java

Constants are evaluated as ints, so 2147483647 + 1 overflows and gives you a new int, which is assignable to int, while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte.

Solution 2 - Java

The literal 127 denotes a value of type int. So does the literal 1. The sum of these two is the integer 128. The problem, in the second case, is that you are assigning this to a variable of type byte. It has nothing to do with the actual value of the expressions. It has to do with Java not supporting coercions (*). You have to add a typecast

byte b = (byte)(127 + 1);

and then it compiles.

(*) at least not of the kind String-to-integer, float-to-Time, ... Java does support coercions if they are, in a sense, non-loss (Java calls this "widening").

And no, the word "coercion" did not need correcting. It was chosen very deliberately and correctly at that. From the closest source to hand (Wikipedia) : "In most languages, the word coercion is used to denote an implicit conversion, either during compilation or during run time." and "In computer science, type conversion, typecasting, and coercion are different ways of, implicitly or explicitly, changing an entity of one data type into another.".

Solution 3 - Java

As an evidence to @MByD:

The following code compiles:

byte c = (byte)(127 + 1);

Because although expression (127 + 1) is int and beyond the scope off byte type the result is casted to byte. This expression produces -128.

Solution 4 - Java

JLS3 #5.2 Assignment Conversion

( variable = expression )

In addition, if the expression is a constant expression (§15.28) of type byte, short, char or int :

A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.


Without this clause, we wouldn't be able to write

byte x = 0;
char c = 0;

But should we be able to do this? I don't think so. There are quite some magic going on in conversion among primitives, one must be very careful. I would go out of my way to write

byte x = (byte)0;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongokuView Question on Stackoverflow
Solution 1 - JavaMByDView Answer on Stackoverflow
Solution 2 - JavaErwin SmoutView Answer on Stackoverflow
Solution 3 - JavaAlexRView Answer on Stackoverflow
Solution 4 - JavairreputableView Answer on Stackoverflow