【问题标题】:Java char to byte castingJava 字符到字节转换
【发布时间】:2015-05-20 10:09:03
【问题描述】:

我一直在测试字符转换,我经历了这个:

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

谁能解释为什么当我向字节添加一个final时它在1中工作正常?

【问题讨论】:

  • 一般来说,从字节转换为字符(反之亦然)不是一个好习惯,因为这会忽略编码。

标签: java scjp


【解决方案1】:

当变量为final时,编译器自动内联其值为1。该值可以表示为char,即:

c = b1;

等价于

c = 1;

其实根据this section on final variablesb1被当成一个常量:

原始类型或String 类型的变量,即final 并使用编译时常量表达式(第15.28 节)初始化,称为常量变量

【讨论】:

  • 还是应该没什么区别
  • @loonytune 是的,编译器会这样做。使用javac 1.7.0_75 验证。
  • 你是正确的,在 java 8 上也得到了验证。我真的很惊讶,这可能与它在编译期间作为符号表中的一个常量条目而不是一个变量有关。很抱歉,赞成您的评论和回答...
  • @loonytune 没问题。在这种情况下,b1 实际上是一个常量变量(您的推理是正确的)。这就是编译器优化代码的原因。
  • 我仍然看不到 JLS 如何将其指定为编译错误。我看到的只是一个常量变量的定义。
【解决方案2】:

bytechar 的转换是一种扩大和缩小原语转换,如Java 语言规范的paragraph 5.1.4 中所述。

正如 JLS 所述,这是通过中间步骤完成的; byte 通过加宽基元转换转换为int,然后int 通过收窄基元转换转换为char(请参阅5.1.3)。

Paragraph 5.2 解释了在您执行作业时何时需要强制转换:

...如果表达式是byteshortcharint 类型的常量表达式 (§15.28):

  • 如果变量的类型是byteshortchar,并且常量表达式的值可以在变量的类型中表示,则可以使用缩小原语转换。

你的变量b1确实是一个常量,但你的变量b2不是,所以这条规则适用于b1但不适用于b2

所以:您可以将b1 分配给c,因为b1 是一个常量,而常量1 的值适合char,但您不能将b2 分配给@987654348 @ 没有强制转换,因为 b2 不是常量。

【讨论】:

  • @PaulDraper 好吧,这些只是语言规范中的官方规则,它准确解释了为什么一个有效而另一个是错误的原因。最后,您必须记住的是,如果它是常数,则不需要强制转换。在这种情况下您不必强制转换的原因是为了方便。
【解决方案3】:

嗯,因为 byte 是有符号类型,而 char 不是,所以你需要为 (2) 应用显式类型转换

c = (char)b2;

final 语句也适用于 1,因为在编译之前,编译器能够确认没有因转换而导致的损失,因为 '1' 在 char 的范围内,尝试将 '-1' 与相同的 final (1) 中的语句会再次出现编译错误。

所有这一切都归结为有符号和无符号类型之间的类型兼容性。这需要在 java 中显式完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多