22

If I have a byte variable: byte b = 0;

why does the following work:

   b++;
   b += 1; // compiles

... but this does not ?

   b = b + 1; // compile error

Does compiler understand first as byte and second as int ?

[EDIT]

I know casting but I want to draw your attention to the b++, b += 1 and b = b + 1

I think they are equal so why compiler differs them ? what is the difference between

  b += 1 and b = b + 1 ?
  • http://stackoverflow.com/questions/81392/java-why-do-i-receive-the-error-message-type-mismatch-cannot-convert-int-to-by has your answer – pyvi Feb 11 '11 at 13:12
  • 1
    nothing to laugh at :) the + operator practically ensures the int part – bestsss Feb 11 '11 at 13:13
  • 1
    for the edit part: `byte b=0; b+=333;` this is ok. b+=1 is compiled like b=(byte)(b+1) – bestsss Feb 11 '11 at 13:21

8 Answers8

28

Because b += 1 is an equivalent to b = (byte)(b + 1), whereas type of b + 1 is promoted to int (JLS §5.6.2 Binary Numeric Promotion) and therefore its result cannot be assigned to byte without explicit conversion.

From JLS, §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.

axtavt
  • 239,438
  • 41
  • 511
  • 482
  • Is there a way to write a numeric constant so that it is viewed as a byte? If I write 7F it is viewed as a float, 7L is a long and so on. Would something like 7B be viewed as a byte? – BigMac66 Feb 11 '11 at 14:07
  • @BigMac66, `static final byte C1 = 11;// this is a byte` but still adding C1+C1 is not a byte, yet `static final byte C2 = C1 + C1;` is correct (b/c it's calculated by the compiler not the runtime), remove `final` from C1 and it's an error. – bestsss Feb 11 '11 at 14:48
  • I get that, what I am asking is when you write a primitive constant value you can append a letter to designate the type you intend that constant to be, is there a letter for the byte primitive? So far I can only find L (long), D (double) and F (float) - are there any others? – BigMac66 Feb 11 '11 at 17:33
  • 1
    @BigMac66: There are no other suffixes, and perhaps there is no need in them, since compile-time constants of type 'int' can be converted to narrower types implicitly when necessary. – axtavt Feb 11 '11 at 17:36
3

Possible loss of precision is the problem. Cast it and it is OK.

b = (byte) (b + 1);
Costis Aivalis
  • 13,680
  • 3
  • 46
  • 47
  • The answer is correct but I still don’t like the explanation. If possible loss of precision were a valid reason here, then the same should be prohibited for integers. After all, `Integer.MAX_VALUE + 1` has the same (or a similar) problem. – Konrad Rudolph Feb 11 '11 at 14:50
  • You are right. The compiler protects you better with bytes than integers: b = 127; is OK for the compiler, while b = 128; is not and must be casted before it gives you a -128 value which is correct. Not so with integers. On the other hand you can say int i = 2147483647; which is Integer.MAX_VALUE and if you go up by one int i = 2147483648; you do get a compiler error "integer number too large". I think axtavt explains the situation well. With the byte we have a promotion with the int not. – Costis Aivalis Feb 11 '11 at 15:25
2

In java the default for integers is int, and for floating point numbers it is double. So b is by default converted to integer to perform the operation. So the resultant answer needs to be typecasted before being stored to prevent any possible loss of precision. But b+=1 does it automatically.

deniro
  • 23
  • 5
2

Yes, the result of the +-operation is int, so a cast is needed in order to assign it to a byte variable.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
1

operands of type byte and short are automatically promoted to int before being handed to the operators

so when you do byte b= b + 1; it considers it "int" as an operation is performed on byte value. so to avoid this we use b+=1; here it is automatically typecasted to byte.

user3137648
  • 786
  • 1
  • 7
  • 10
0

I don't buy the argument about loss of precision, since the compiler won't protect you in a similar fashion when dealing with ints and longs. I think the real answer lies with the JLS simply having better support for ints than bytes, as stated in this answer: https://stackoverflow.com/a/13211737/567000

Community
  • 1
  • 1
Søren Boisen
  • 1,669
  • 22
  • 41
0

You need to cast to byte:

b = (byte) (b + 1);
DVK
  • 126,886
  • 32
  • 213
  • 327
  • edited. I know that casting solve this problem but I want to learn other thing that written in editted part –  Feb 11 '11 at 13:19
0

Doing b + 1 widens the result to integer, and assigning back to byte b would cause loss of precision. Explained: Conversions and Promotions. But I like axtavt's answer better.

omerkudat
  • 9,371
  • 4
  • 33
  • 42