【问题标题】:Inconsistent "possible lossy conversion from int to byte" compile-time error不一致的“从 int 到字节的可能有损转换”编译时错误
【发布时间】:2019-10-03 09:36:37
【问题描述】:

检查以下代码sn-ps:

片段 #1

int a=20;
int b=30;
byte c= (a>b)? 20:30;
Error:
incompatible types: possible lossy conversion from int to byte
byte c= (a>b)? 20:30;

片段 #2

int a=20;
int b=30;
byte h1=70;
byte c= (a>b)? 20:h1;

片段#3

int a=20;
int b=30;
byte h1=70;
byte h2=89;
byte c= (a>b)? h1:h2;

片段 #4

byte c= (true)? 20:30;

除了 Snippet #1 之外,所有这些都可以正常编译。这种行为如何合理?如果 Snippet #1 产生“可能的有损转换”错误,Snippets #2 和 4 也应该,因为它们仍然包含 int 类型的文字。为什么编译成功?

【问题讨论】:

  • 如果将int 更改为final int(常量),编译器将看到ab 的值在-128..127 字节范围内。对于 int variables,编译器不会进行此类评估,并假定 int 可能会溢出字节范围。
  • @JoopEggen 但是为什么 a 和 b 的范围很重要,甚至它们的数据类型也很重要; (a>b) 是一个条件,将评估为真或假,并基于此将 20 或 30 分配给变量 c。我不明白为什么变量 a 和 b 的范围和类型很重要。重要的是文字 20 和 30 或变量 h1 和 h2 的范围和数据类型,我们用来分配给变量 c。但从代码 4 看来,变量 a 和 b 的数据类型和范围很重要。
  • 在将较大的类型变量分配给较小的类型变量时,通常会出现警告/错误,因为信息意外丢失。但是我希望有更好的答案来阐明 java 的状态

标签: java compiler-errors language-specifications


【解决方案1】:

J.L.S 15.25. 解释了这种行为。

片段 #1:

如果第二个和第三个操作数的类型相同(可能是空类型),那么就是条件表达式的类型

第二个和第三个操作数都是int字面量,所以表达式的类型也是int,如果没有显式转换,它不能分配给byte变量。因此编译错误。

片段 #2:

如果其中一个操作数是 T 类型,其中 T 是 byte、short 或 char,而另一个操作数是 int 类型的常量表达式(第 15.28 节),其值可在类型 T 中表示,则条件表达式是T。

一个操作数是byte,另一个是int字面量,其值可以表示为byte,所以表达式的类型是byte,可以赋值给byte变量.

片段 #3:

如果第二个和第三个操作数的类型相同(可能是空类型),那么就是条件表达式的类型

第二个和第三个操作数都是byte,所以表达式的类型是byte,可以赋值给一个byte变量。

片段 #4:

由于所有 3 个操作数都是常量,因此整个三元表达式是一个常量表达式,因此编译器将此表达式视为一个简单的赋值 - byte c = 20; - 这是有效的。

【讨论】:

    【解决方案2】:

    language spec 中描述了此行为。


    案例 1 和案例 3 描述相同点:

    如果第二个和第三个操作数的类型相同,那么就是条件表达式的类型。

    第一种情况,操作数是int类型,所以整体表达式是int类型,所以不兼容。第三种情况是byte类型的操作数,所以结果是兼容的。


    案例 2 让我感到惊讶:我本来预计它也会失败,因为 int 操作数会导致条件表达式为 int 类型。

    但是,以下几点描述了此行为:

    如果其中一个操作数是 T 类型,其中 Ti 是 byte、short 或 char,而另一个操作数是 int 类型的常量表达式(第 15.28 节),其值可以用 T 类型表示,则条件的类型表达式是 T。

    20 是一个适合字节的常量表达式,因此结果是一个字节。


    情况 4 也由用于情况 1 和 3 的“相同类型的操作数规则”来描述;但是,条件现在保持不变的事实使其成为constant expressions

    当分配给更窄类型的变量时,int 类型的常量表达式被隐式缩小,如Assignment contexts 中所述:

    如果变量是 byte、short 或 char 类型,并且常量表达式的值可以用变量的类型表示,则可以使用缩小原语转换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-27
      • 1970-01-01
      • 2014-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多