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

- 30,738
- 21
- 105
- 131

- 1,197
- 1
- 10
- 14
-
16I have a genuine doubt too: why is the `byte` data type such a pain?! – BoltClock Jul 31 '11 at 12:07
-
9it's definitely a design mistake that `byte` is signed instead of unsigned. – irreputable Jul 31 '11 at 13:10
-
4@BoltClock It's only a pain when you don't know how to use it properly. http://stackoverflow.com/questions/397867/port-of-random-generator-from-c-to-java/397997#397997 – starblue Jul 31 '11 at 14:12
-
2@starblue, is there any real-life example where the Java byte type is applicable? – Thorbjørn Ravn Andersen Jul 31 '11 at 21:26
-
If there is data that is specified as a byte then use a Java `byte` for clarity, e.g. in parameters. In that case the fact that you can't assign `int` values will even catch some bugs. Or use `byte` to save space in arrays. I wouldn't use `byte` for a single value that just happens to fit in a byte. – starblue Aug 01 '11 at 06:49
-
Josh Bloch always mentions that issue. http://www.youtube.com/watch?v=hcY8cYfAEwU around min 12. – ahmet alp balkan Aug 03 '11 at 21:27
4 Answers
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
.

- 135,866
- 28
- 264
- 277
-
10Actually, today I read some of **Java puzzlers** , including a puzzle just about that... See here: http://www.javapuzzlers.com/java-puzzlers-sampler.pdf - puzzle 3 – MByD Jul 31 '11 at 13:47
-
3The issue is the type `int` due to binary numeric promotion, the value `127` is a red herring. – starblue Jul 31 '11 at 14:10
-
I would prefer constants being evaluated with infinite precision and also giving an error on int i = 2147483647 + 1; – Eduardo Aug 06 '11 at 16:47
-
@MByD: As you said "`while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte.`", does this mean that 50 + 1 will be evaluated as `byte` and hence is assignable to `byte`? – Bhushan Oct 26 '11 at 20:27
-
1@10101010 - not exactly. it will be assignable to byte, but first (according to the standard) it will be evaluated as int. – MByD Oct 27 '11 at 05:03
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.".

- 18,113
- 4
- 33
- 52
-
Your code example should probably be byte b = (byte)127 + 1; which is 'Add 1 to a maxed out byte value', your example just turns int value of 128 into a byte value. – NKCSS Jul 31 '11 at 12:48
-
6@NKCSS - I don't think you're right, this - `(byte)(127 + 1)` cast 128 (integer) to a byte, while this `(byte)127 + 1` cast the 127 to a byte, but then again to an int, since it's added to 1(int) and you get 128 (int) and error stays. – MByD Jul 31 '11 at 12:58
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;

- 44,725
- 9
- 65
- 93
-
as to the question should we be able to... i don't see really anything wrong with `byte x = 0` but then again, I am a C programmer. – Grady Player Aug 01 '11 at 03:42
-
I could maybe see an argument against char c = 0, but why is byte x = 0 wrong? – Michael Burge Aug 01 '11 at 14:35
-
It's misleading to untrained eyes, thinking they are assigning a byte 0 to a byte variable. Not much harm in this example, but in general, operating on byte/short/char could get very confusing due to implicit conversions. They are much more complicated than people would think. I want as much clarity as possible in my code, don't introduce any uncertainty for the sake of saving a few key strokes. – irreputable Aug 01 '11 at 15:44
-
Does a similar rule apply when the narrowing primitive conversion is from long to int, e.g. int i = 1+0L ? Just asking because your quoted text explicitly leaves that case out. – Erwin Smout Aug 03 '11 at 14:43
-
-
-
@ErwinSmout: To the Java Virtual Machine, all numeric expressions are `int`, `long`, `float`, or `double`. Given `byte byteArr[]`, a statement like `byteArr[1] = byteArr[0]` will convert `byteArr[0]` to an `int`, and then store the result to `byteArr[1]` while discarding the upper bits. An explicit cast to `byte` doesn't really "convert" anything--it masks off the upper bits, leaving the value as an `int`, and then *tells the compiler to allow it to be stored to things of type `byte`*. If the compiler didn't squawk at an attempt to store an `int` to a `byte`, the runtime wouldn't care. – supercat Jul 11 '14 at 21:22
-