与三元/条件操作员的Java中的异常方法超载结果
您能以详细的方式解释为什么预期结果不正确?正如大多数读者所期望的那样,输出是 byte char int byte
,但是当然,这不是正确的答案。
public class Tester {
public static String test(byte b) {
return "Byte ";
}
public static String test(char c) {
return "Char ";
}
public static String test(int i) {
return "Int ";
}
public static void main(String[] args) {
byte b = 0;
char c = 'A';
System.out.print(test(true ? b : c));
System.out.print(test(false ? b : c));
System.out.print(test(true ? 0 : 'A'));
System.out.print(test(false ? 'A' : (byte)0));
}
}
正确的结果是 int int char int
。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是因为过载分辨率取决于参数表达式的编译时类型,而不是参数的运行时类型。请参阅JLS :
参数表达式
是吗? B:C
具有int
的类型,因此调用了int
方法。这是在,据说如果没有特殊情况匹配(在这里都不匹配),则有条件表达式的类型是应用于应用数字促销到第二和第三操作数:这就是为什么
是真的吗? B:C
是类型int
。false也是如此吗? B:C
和false? 'a':(字节)0
。条件是什么都没关系。表达式的类型由第二和第三操作数的类型确定。至于
test(true?0:'a')
,可以用我上面省略的规则来解释,只是 最后一个“否则...”在这种情况下,表达式“
0
”是“类型int
的常数表达式,其值在类型char> char
中表示的值” 。考虑条件表达式类型的一种方法是,这是两个分支的表达式可以“合适”的最小类型。对于
字节b
和char c
,int
是最小的类型,可以适合两者。对于0
和'a'
,char
足以适合两者在char
的范围内。This is because overload resolution depends on the compile-time type of the argument expressions, not the runtime type of the argument. See JLS 15.12.2.2:
The argument expression
true ? b : c
has the typeint
, so theInt
method is called. This is specified in the JLS 15.25.2, where it is said that if none of the special cases match (none of them do here), then the type of the conditional expression is the type after applying numeric promotion to the second and third operands:This is why
true ? b : c
is of typeint
. The same goes forfalse ? b : c
andfalse ? 'A' : (byte)0
. It doesn't matter what the condition is. The type of the expression is determined by the types of the second and third operands.As for
test(true ? 0 : 'A')
, this can be explained by a rule that I omitted above, just before the last "Otherwise..."In this case, the expression "
0
" is a "a constant expression of typeint
with a value that is representable in the typechar
".One way to think about the type of a conditional expression, is that it's the smallest type that the expressions of both of the branches can "fit". For a
byte b
and achar c
,int
is the smallest type that can fit both of them. For0
, and'A'
,char
is enough to fit both, as it is known that0
is in the range ofchar
.对于Java中有条件表达式的类型,请始终请咨询JLS图表(第15.25节)。
中的符号“ bnp(x,y)”是指 binary Numeric促进 x 和 y 的b of ,以及“ t” |。bnp(..)表示,如果一个操作数是类型
int
的常数表达式,则可以在T型中表示,则如果操作数在类型T中不可用,则使用二进制数字促销。对于前两个电话,我们有一个
char
和byte
,因此结果是“ BNP(byte,char)”或类型int
int 。对于第三个调用,我们具有类型
int
和char
的常数表达式,并且该值可表示为char
(它是0
),因此结果是类型char
。对于第四个呼叫,我们有一个
字节
和char
,因此我们回到“ BNP(BYTE,char)”,这是类型int 。
For the type of a conditional expression in Java, always consult the JLS charts (Section 15.25).
where the notation "bnp(x, y)" means the type that is the result of binary numeric promotion of x and y, and the form "T | bnp(..)" means that if one operand is a constant expression of type
int
and may be representable in type T, then binary numeric promotion is used if the operand is not representable in type T.For the first 2 calls, we have a
char
and abyte
, so the result is "bnp(byte, char)", or the typeint
.For the third call, we have a constant expression of type
int
and achar
, and the value is representable as achar
(it's0
), so the result is the typechar
.For the fourth call, we have a
byte
and achar
, so we back to "bnp(byte,char)", which is the typeint
.将其表达式转换为公共类型,以便将其结果存储的变量。
想象一下,如果您有这样的表达:
char v =< mycondition> ? 'a':0l;
只有在条件为
true
的情况下,先前的语句才有意义,但是如果这是false> false
和0l < /代码>要退还?
长
和char
不是相同的数据类型。因此,编译器需要在不丢失精度的情况下找到一种常见的类型,以允许将两个表达式返回并分配给适合它们的变量。无论疾病的结果如何,都会拾取所得数据类型。在这种情况下,
长
不能将其施加到int
,然后char
,因为它将失去精度。而char
可以将其施加到int
,然后晋升为long
。这就是为什么可以像这样正确编写的先前语句:long v =&lt; mycondition&gt; ? 'a':0l;
在您的示例中,第一个三元运算符具有
byte
和char> char
。byte
和char
可以升级为int
,为byte
, char> char and Code>和int
分别占用1
,2
和4
bytes。相反,相反,char
将被施加到byte
是不可能的,因为这将导致精确损失(along <
long << /代码>占8个字节)。通过应用相同的促销逻辑,您还可以解释其余案例,除第三个情况外,需要以下 table 。
The ternary operator converts its expressions to a common type in order for a variable to store its result.
Imagine if you had an expression like this:
char v = <myCondition> ? 'a' : 0L;
The previous statement would make sense only if the condition was
true
, but what about if this wasfalse
and0L
was to be returned?long
andchar
are not the same data type. So, the compiler needs to find a common type, without losing precision, in order to allow both expressions to be returned and assigned to a variable suitable for both of them. The resulting data type is picked up regardless of the condition's outcome.In this case,
long
cannot be cast toint
and thenchar
, as it would lose precision. Whereas,char
could be cast toint
and then promoted tolong
. This is why the previous statement can be correctly written like so:long v = <myCondition> ? 'a' : 0L;
In your example, the first ternary operator has a
byte
and achar
. Bothbyte
andchar
can be promoted toint
, asbyte
,char
andint
respectively occupy1
,2
and4
bytes. Instead, the other way around, where achar
would be cast to abyte
wouldn't be possible, as this would cause a precision loss (along
occupies 8 bytes). By applying the same logic of promotion, you can also explain the remaining cases, except for the third one, which requires the following table.表15.25-a在描述了
的结果是什么类型?:
操作员是,具体取决于贡献类型。您的第一个示例涉及
byte
和char
,因此结果是BNP(二进制数字促销),除了double> double
,外, float
或长
,结果类型为int
。对他人也一样。
Table 15.25-A in the Java language specification describes what type the result of a
?:
operator is, depending on the contributing types.Your first example involves
byte
andchar
, so the result is a bnp (binary numeric promotion) of these, and for anything butdouble
,float
, orlong
, the resulting type isint
.Same thing for the others.