6

Why do I get an error when

       int i=123;
       byte b=i;

But not in this case

      final int i=123;
      byte b=i;
alia
  • 459
  • 4
  • 16
  • 2
    @Turamarth Well spotted! The answer there explains this one, too. – S.L. Barth is on codidact.com Aug 01 '18 at 07:05
  • But there the variables are all of byte types not int – alia Aug 01 '18 at 07:11
  • 1
    @alia yes, but explanation is the same. – alex Aug 01 '18 at 07:14
  • @alia That does not matter. The crucial part is that you can change a non-final int to something too big for byte. Only making the int final will show the compiler that the int will fit into the byte. The other question just replaced one big int by two smaller bytes that are summed. – Malte Hartwig Aug 01 '18 at 07:14
  • 1
    @alia As mentioned, it has to do with whether or not the `int` will fit in a `byte`. To see this set `final int i` to something greater than `127` (max value of a `byte`) or to something less than `-128` (min value of a `byte`) and you'll get a compilation error again. – Slaw Aug 01 '18 at 07:16

2 Answers2

6

When you initialize a final variable with a constant expression, it will become a compile-time constant. Essentially, when the code is compiled, it will just hardcode the value everywhere your variable is added. You can see this in the byte code:

 0  bipush 123
 2  istore_1 [i]
 3  bipush 123
 5  istore_2 [b]

As you can see, it pushes the value 123 directly into the byte (same as byte b = 123), and that is a valid value for a byte. It would not work with a value that is outside the allowed range for bytes.

If the variable is not final (or not initialized with a constant expression), then the compiler will see it as a normal variable, and normal rules for assigning are applied. Meaning that to assign an int to a byte it needs to be casted:

int i = 123;
byte b = (byte) i;

Which produces this bytecode:

0  bipush 123
2  istore_1 [i]
3  iload_1 [i]
4  i2b
5  istore_2 [b]
TiiJ7
  • 3,332
  • 5
  • 25
  • 37
  • but what will happen when the variable is not final? – alia Aug 01 '18 at 07:23
  • @alia In that case the compiler cannot replace the value at compile time and the normal assignment rules will apply (aka needs a cast to `byte`). In the `final` case it basically doen't need to care about the type of `i` since it isn't used when assigning `b`. – TiiJ7 Aug 01 '18 at 07:34
-1

Boolean, byte, short, int, long are all ints by default, all are ints, and can be assigned as long as they do not exceed their range of values

The variable modified by final is determined at compile time and cannot be changed.

Variables modified by final do not automatically change the type

final int i = 127;
byte b = i;

final int i = 128;
byte b = i;        // There will be compilation errors
Destiny.Wang
  • 169
  • 8
  • but what actually happens when the variable is not a final?why do we get error then – alia Aug 01 '18 at 07:27
  • @alia the variable modified by final will not change and will be optimized by the JVM. When the final modified variable is assigned a value, it will be transformed according to the type of the left variable, as the final type of the final variable. – Destiny.Wang Aug 01 '18 at 07:32