char and byte with final access modifier - java

348 views Asked by At

Please take a look at below example i cant understand the relation between char and byte

byte b = 1;
char c = 2;

c = b; // line 1

Give me compilation Error because c is type of char and b is type of byte so casting is must in such condition

but now the tweest here is when i run below code

final byte b = 1;
char c = 2;

c = b; // line 2

line 2 compile successfully it doesn't need any casting at all so my question is why char c behave different when i use final access modifier with byte

3

There are 3 answers

0
Sotirios Delimanolis On BEST ANSWER

Because qualifying it with final makes the variable a constant variable, which is a constant expression. So

final byte b = 1;
char c = 2;

c = b; // line 2

actually becomes

final byte b = 1;
char c = 2;

c = 1;

And the compiler has a guarantee that the value 1 can fit in a char variable.

With a non constant byte variable, there is no such guarantee. byte is signed, char is unsigned.

1
AlexR On

I guess that it happens because java compiler replaces references to final variables by their values (almost like pre-processor in C). Since value 1 is legal for type char the last line is transformed to

c = 1;

that is compiled successfully.

0
Elliott Frisch On

You are running into JLS-5.1.4 Widening and Narrowing Primitive Conversion,

The following conversion combines both widening and narrowing primitive conversions:

  • byte to char

First, the byte is converted to an int via widening primitive conversion (§5.1.2), and then the resulting int is converted to a char by narrowing primitive conversion (§5.1.3).

final byte b = 1;
char c = (char) ((int) 2); // <-- 2 is an int literal
c = (char) ((int) 1); // <-- b is 1 a byte literal

If you examine the bytescodes with javap -v you'll see the the value 1 has already replaced the variable b after compilation.

public static void main(java.lang.String[]) throws java.lang.Exception;
  descriptor: ([Ljava/lang/String;)V
  flags: ACC_PUBLIC, ACC_STATIC
  Exceptions:
    throws java.lang.Exception
  Code:
    stack=2, locals=3, args_size=1
       0: iconst_1 
       1: istore_1 // b = 1
       2: iconst_2
       3: istore_2 // c = 2
       4: iconst_1 // integer1.
       5: istore_2 // c = 1.