与三元/条件操作员的Java中的异常方法超载结果

发布于 2025-01-25 00:43:50 字数 707 浏览 2 评论 0 原文

您能以详细的方式解释为什么预期结果不正确?正如大多数读者所期望的那样,输出是 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

Could you explain in a detailed manner why the expected result is not correct? As most of the readers expect that the output is Byte Char Int Byte, but of course it is not the correct answer.

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

The correct result is Int Int Char Int.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

誰認得朕 2025-02-01 00:43:50

这是因为过载分辨率取决于参数表达式的编译时类型,而不是参数的运行时类型。请参阅JLS

参数表达式是吗? B:C 具有 int 的类型,因此调用了 int 方法。这是在,据说如果没有特殊情况匹配(在这里都不匹配),则有条件表达式的类型是应用于应用数字促销到第二和第三操作数:

如果表达式是以下一个:

,则表达式出现在数字选择上下文中。

  • 数字条件表达式的第二或第三操作数
  • [...]

数字促进确定数字上下文中所有表达式的促进类型。 [...]规则如下:

[...](在A 简短和A byte 表达式的情况下,这些规则都不匹配)

否则,没有任何一种表达式为double,float或long。在这种情况下,上下文决定了如何选择促进的类型。

在数字选择上下文中,以下规则适用:

  • [...](在简短字节表达式的情况下,这些规则都不匹配)

  • 否则,促进的类型为 int ,所有不适合类型的表达式 int 经历原始转换为 int

这就是为什么是真的吗? B:C 是类型 int false也是如此吗? B:C false? 'a':(字节)0 。条件是什么都没关系。表达式的类型由第二和第三操作数的类型确定。

至于 test(true?0:'a'),可以用我上面省略的规则来解释,只是 最后一个“否则...”

  • 否则,如果任何类型的表达式 char ,并且其他每个表达式都是类型 char> char 的常数表达式 int 具有在类型 char 中表示的值,然后促进的类型为 char int 表达式经历了狭窄的原始转换为 char

在这种情况下,表达式“ 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 type int, so the Int 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:

An expression appears in a numeric choice context if the expression is one of the following:

  • The second or third operand of a numeric conditional expression
  • [...]

Numeric promotion determines the promoted type of all the expressions in a numeric context. [...] The rules are as follows:

[...] (none of these rules match in the case of a short and a byte expression)

Otherwise, none of the expressions are of type double, float, or long. In this case, the kind of context determines how the promoted type is chosen.

In a numeric choice context, the following rules apply:

  • [...] (none of these rules match in the case of a short and a byte expression)

  • Otherwise, the promoted type is int, and all the expressions that are not of type int undergo widening primitive conversion to int.

This is why true ? b : c is of type int. The same goes for false ? b : c and false ? '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..."

  • Otherwise, if any expression is of type char, and every other expression is either of type char or a constant expression of type int with a value that is representable in the type char, then the promoted type is char, and the int expressions undergo narrowing primitive conversion to char.

In this case, the expression "0" is a "a constant expression of type int with a value that is representable in the type char".

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 a char c, int is the smallest type that can fit both of them. For 0, and 'A', char is enough to fit both, as it is known that 0 is in the range of char.

逆流 2025-02-01 00:43:50

对于Java中有条件表达式的类型,请始终请咨询JLS图表(第15.25节)

第三→ byte char int
第二↓        
字节 byte bnp(byte,char) byte | BNP(字节,int)
字节 byte bnp(byte,char) byte | BNP(字节,int)
bnp(短,char) 短| BNP(简短,int)
bnp(短,char) 短| BNP(简短,int)
char bnp(char,byte) bnp(char,short) char char | BNP(char,int)

中的符号“ 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).

3rd → byte short char int
2nd ↓        
byte byte short bnp(byte,char) byte | bnp(byte,int)
Byte byte short bnp(Byte,char) byte | bnp(Byte,int)
short short short bnp(short,char) short | bnp(short,int)
Short short short bnp(Short,char) short | bnp(Short,int)
char bnp(char,byte) bnp(char,short) char char | bnp(char,int)

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 a byte, so the result is "bnp(byte, char)", or the type int.

For the third call, we have a constant expression of type int and a char, and the value is representable as a char (it's 0), so the result is the type char.

For the fourth call, we have a byte and a char, so we back to "bnp(byte,char)", which is the type int.

嘿看小鸭子会跑 2025-02-01 00:43:50

将其表达式转换为公共类型,以便将其结果存储的变量。

想象一下,如果您有这样的表达:

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 是不可能的,因为这将导致精确损失(a long < 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 was false and 0L was to be returned? long and char 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 to int and then char, as it would lose precision. Whereas, char could be cast to int and then promoted to long. 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 a char. Both byte and char can be promoted to int, as byte, char and int respectively occupy 1, 2 and 4 bytes. Instead, the other way around, where a char would be cast to a byte wouldn't be possible, as this would cause a precision loss (a long 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.

风柔一江水 2025-02-01 00:43:50

表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 and char, so the result is a bnp (binary numeric promotion) of these, and for anything but double, float, or long, the resulting type is int.

Same thing for the others.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文