为什么我的字符打印为数字而不是字符? [英] Why is my char printing as a number instead of a character?

查看:212
本文介绍了为什么我的字符打印为数字而不是字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据Java三元运算符表达式? statement1:statement2
如果表达式为true,那么 statement1 将被执行,如果表达式为假,则 statement2 将被执行。



<但是当我跑步时:

  //一些不必要的代码没有显示
char y ='y';
int i = 0;
System.out.print(false?i:y);

我希望它打印 y 但是它的打印 121 ,为什么?



编辑
根据manouti回答,编译器解释为 int ,但如果是这种情况那么为什么我在 i 看到死代码?



如果我做 System.out.print(false?0:x); 那么我得到 y ,那么为什么在这种情况下编译器不能解释为 int

解决方案

您的问题的简短回答是打印的值基于条件表达式求值的类型。



所以你的问题归结为,为什么条件表达式的类型在

  char y ='y之间不同; 
int i = 0;
System.out.print(false?i:y); //打印121

  char y ='y'; 
System.out.print(false?0:y); //打印y

要回答这个问题,我们需要看看 Java语言规范的第15.25节



Java中有三种类型的条件表达式:




  • 布尔值条件表达式

  • 数字条件表达式

  • 参考条件表达式



由于 int char 都可转换为数字类型,因此表达式是数字的示例条件表达式根据此规则:


如果第二个和第三个操作数表达式都是数值表达式,则条件表达式为数字条件表达式。



为了对条件进行分类,以下表达式是数字表达式:




  • 独立形式(第15.2节)的表达式,其类型可转换为数字类型(§4.2,§5.1.8)。


鉴于此,确定整个表达式类型的规则如下:


15.25.2。数字条件表达式



数字条件表达式是独立表达式(第15.2节)。



类型数值条件表达式的确定如下:




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


  • 如果第二个和第三个操作数之一是原始类型T,而另一个的类型是应用装箱的结果将转换(第5.1.7节)转换为T,然后条件表达式的类型为T.


  • 如果其中一个操作数的类型为byte或Byte,另一个是short或Short类型,那么条件表达式的类型很短。


  • 如果其中一个操作数是T类型,其中T是字节,short或char,另一个操作数是int类型的常量表达式(第15.28节),其值可在类型T中表示,然后是条件表达式的类型n是T.


  • 如果其中一个操作数是T类型,其中T是Byte,Short或Character,另一个操作数是常量表达式类型为int的类型为U,它是将取消装箱转换应用于T的结果,则条件表达式的类型为U.


  • 否则,二进制数字提升(第5.6.2节)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。




请注意,二进制数字促销执行值集转换(第5.1.13节)并可执行拆箱转换(第5.1.8节)。


请注意,第四条规则准确描述了第二个例子;第二个操作数是 int 0 )类型的常量,第三个是 char ,因此条件表达式将计算为 char 。这将导致编译器使用 print(char)方法,该方法将打印 y



然而,当您改为传递变量而不是传递常量时,您可以归结为最后一条规则,即... 。条件表达式的类型是第二个和第三个操作数的提升类型。



如果你看一下 JLS的第5.6.2节,它描述了规则对于类型提升,如下所示:


当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示一个值,即可转换为数字类型,以下规则适用:


  1. 如果任何操作数属于引用类型,则为进行拆箱转换(第5.1.8节)。


  2. 扩展基元转换(第5.1.2节)适用于转换由以下规则指定的一个或两个操作数:




    • 如果任一操作数的类型为double,则另一个操作数转换为double。


    • 否则,如果任一操作数的类型为float,则另一个操作数转换为float。


    • 否则,如果任一操作数的类型为long,则另一个操作数转换为long。


    • 否则,两个操作数都将转换为int类型。




通过关注这些规则,表达式的类型将是 int ,因此编译器将使用 print(int)方法,将打印 121 (ascii值为 y )。


As per the Java ternary operator expression ? statement1 : statement2, if expression is true then statement1 will be executed, if expression is false then statement2 will be executed.

But when I run:

// some unnecessary codes not displaying
char y = 'y';
int i = 0;
System.out.print(false ? i : y);

I am expecting it to print y but its printing 121, why?

EDIT As per the manouti answer, the compiler interprets as int, but if that is the case then why I am seeing dead code at i?

If I do System.out.print(false ? 0 : x); then I am getting y, so why in this case doesn't the compiler interpret as int?

解决方案

The short answer to your question is that the value printed is based on the type that the conditional expression evaluates to.

So really your question boils down to, why does the type of the conditional expression differ between

char y = 'y';
int i = 0;
System.out.print(false ? i : y); // prints 121

and

char y = 'y';
System.out.print(false ? 0 : y); // prints y

To answer that, we'll need to take a look at section §15.25 of the Java Language Specification.

There are three types of conditional expression in Java:

  • Boolean Conditional Expressions
  • Numeric Conditional Expressions
  • Reference Conditional Expressions

Since both int and char are convertible to a numeric type, the expression is an example of a numeric conditional expression according to this rule:

If both the second and the third operand expressions are numeric expressions, the conditional expression is a numeric conditional expression.

For the purpose of classifying a conditional, the following expressions are numeric expressions:

  • An expression of a standalone form (§15.2) with a type that is convertible to a numeric type (§4.2, §5.1.8).

Given that, the rule for determining the type of the entire expression is given as follows:

15.25.2. Numeric Conditional Expressions

Numeric conditional expressions are standalone expressions (§15.2).

The type of a numeric conditional expression is determined as follows:

  • If the second and third operands have the same type, then that is the type of the conditional expression.

  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

  • If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short.

  • If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T.

  • If one of the operands is of type T, where T is Byte, Short, or Character, and the other operand is a constant expression of type int whose value is representable in the type U which is the result of applying unboxing conversion to T, then the type of the conditional expression is U.

  • Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.

Note that binary numeric promotion performs value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8).

Notice that the fourth rule exactly describes the second example; the second operand is constant of type int (0) and the third is a char, so the conditional expression will evaluate to char. This will cause the compiler to use the print(char) method, which will print y.

However when you instead pass in a variable instead of a constant, you fall down to the last rule which says that "...the type of the conditional expression is the promoted type of the second and third operands."

If you take a look at section §5.6.2 of the JLS, it describes the rules for type promotion as follows:

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:

  1. If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).

  2. Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

    • If either operand is of type double, the other is converted to double.

    • Otherwise, if either operand is of type float, the other is converted to float.

    • Otherwise, if either operand is of type long, the other is converted to long.

    • Otherwise, both operands are converted to type int.

By following these rules, the type of the expression will be int, and so the compiler will use the print(int) method, which will print 121 (the ascii value of y).

这篇关于为什么我的字符打印为数字而不是字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆