Java char to byte casting
Asked Answered
D

3

23

I have been testing the char casting and I went through this:

public class Test {
    public static void main(String a[]) {
        final byte b1 = 1;
        byte b2 = 1;
        char c = 2;

        c = b1; // 1- Working fine
        c = b2; // 2 -Compilation error
    }
}

Can anyone explain why it's working fine in 1 when I added a final to the byte?

Disagreement answered 20/5, 2015 at 10:9 Comment(1)
In general, casting from bytes to characters and vice versa is not a good practice since this ignores encoding.Heartwood
I
19

When the variable is final, the compiler automatically inlines its value which is 1. This value is representable as a char, i.e.:

c = b1;

is equivalent to

c = 1;

In fact, according to this section on final variables, b1 is treated as a constant:

A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable.

Inside answered 20/5, 2015 at 10:11 Comment(5)
still should make no differenceHuba
@loonytune Yes the compiler does this. Verified using javac 1.7.0_75.Inside
You are correct, verified on java 8 as well. I'm really surprised, it has probably to do with something like it being a constant entry in the symbol table during compilation and not being a variable at all. Sorry for that, upvoted your comment and answer ...Huba
@loonytune No problem. In this case, b1 is actually a constant variable (your reasoning is correct). That's why the compiler optimizes the code.Inside
I still don't see how the JLS specifies this as a compile error. All I see is the definition of a constant variable.Weinberg
N
10

The conversion from byte to char is a widening and narrowing primitive conversion, as described in paragraph 5.1.4 of the Java Language Specification.

As the JLS describes, this is done via an intermediate step; the byte is converted to int via a widening primitive conversion and then the int is converted to char via a narrowing primitive conversion (see 5.1.3).

Paragraph 5.2 explains when a cast is necessary when you do an assignment:

... 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.

Your variable b1 is indeed a constant, but your variable b2 is not, so this rule applies for b1 but not for b2.

So: you can assign b1 to c because b1 is a constant and the value of the constant, 1, fits in a char, but you cannot assign b2 to c without a cast because b2 is not a constant.

Nesta answered 20/5, 2015 at 10:25 Comment(1)
@PaulDraper Well, these are just the official rules from the language specification, that explain exactly why one works and the other is an error. In the end all you have to remember is that you don't need to cast if it's a constant. The reason why you don't have to cast in that case is for convenience.Nesta
T
0

Well , its because byte is a signed type while char is not, so u need to apply explicit type conversion for (2)

c = (char)b2;

also the final statement worked for 1 because prior to compilation , the compiler is able to confirm that there is no loss due to conversion since '1' is in the range of char , try putting '-1' with the same final statement in (1) you will again get a compilation error.

All this boils down to the type compatibility between signed and unsigned types..which needs to be done explicitly in java.

Toms answered 20/5, 2015 at 10:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.