1
byte b1 = 3 + 5;

The literals 3, 5 and 3 + 5 are of type int. The expression above works because Java internally converts the result of 3 + 5 from int to byte, or?

The same explanation should work in the case of b2:

    byte b1 = 3 + 5;
    byte b2 = b1 + 5; // Type mismatch: cannot convert from int to byte

But it does not.

Why?

mrbela
  • 4,477
  • 9
  • 44
  • 79
  • 9
    The difference: `3` and `5` are compile time constants, so `3 + 5` can be evaluated at compile time and the whole line is simplified to `byte b1 = 8;`. But `b1` is not a compile time constant, so this does not work with the line `byte b2 = b1 + 5;`. – Jesper Mar 19 '21 at 11:05
  • Watch this conversation, maybe it could help https://stackoverflow.com/questions/9581530/converting-from-byte-to-int-in-java – Eitan Rosati Mar 19 '21 at 11:06
  • 4
    The second conversation works if you declare b1 `final`. The compiler simply considers the possibility that the non final variable might have changed by the second line and therefor be to big to fit in another byte – OH GOD SPIDERS Mar 19 '21 at 11:09
  • The operands of `+` undergo binary numeric promotion: in the second case, it is effectively `(int) b1 + 5`, the result of which is a non-compile-time constant `int`. In the first case, both operands are compile-time constants (and ints), so the result is a compile-time constant int; the compiler can check that result is within the range of `byte`, and so can implicitly narrow the result. – Andy Turner Mar 19 '21 at 11:35

2 Answers2

0

The operands of + undergo binary numeric promotion: that is, they are widened where necessary to make them compatible for addition. The rule is quite simple:

  • If either operand is a double, widen the other to double
  • If either operand is a float, widen the other to float
  • If either operand is a long, widen the other to long
  • Otherwise, widen them both to int

in the second case, it is effectively (int) b1 + 5, the result of which is a non-compile-time constant int. This can't be guaranteed to be in the range of byte, so the compiler complains.

In the first case, both operands are compile-time constant ints, so the result is a compile-time constant int; the compiler can check that result is within the range of byte, and so can implicitly narrow the result.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
0

ints are implicitly cast to bytes in your previous assignments, to mimic the effect in the last statement you need to do it explicitly after java promotes b1 + 5 to an int, like this:

byte b2 = (byte) b1 + 5;

alternatively if you declare b1 as final, the compiler will check the ranges and do the assignment (with an implicit cast) as you expected originally, since 3 + 5it is in the range of bytes and b1 will not be changing its value (3):

final byte b1 = 3;
byte b2 = b1 + 5;
HolyLance
  • 51
  • 4