Java 为什么我的字符打印为数字而不是字符?

Java 为什么我的字符打印为数字而不是字符?,java,char,int,Java,Char,Int,根据Java三元运算符表达式?语句1:语句2, 如果expression为true,则执行statement1,如果expression为false,则执行statement2 但当我跑步时: // some unnecessary codes not displaying char y = 'y'; int i = 0; System.out.print(false ? i : y); 我希望它打印y,但它打印121,为什么 编辑 根据manouti的回答,编译器解释为int,但如果是这种情

根据Java三元运算符
表达式?语句1:语句2
, 如果
expression
为true,则执行
statement1
,如果
expression
为false,则执行
statement2

但当我跑步时:

// some unnecessary codes not displaying
char y = 'y';
int i = 0;
System.out.print(false ? i : y);
我希望它打印
y
,但它打印
121
,为什么

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


如果我执行
系统输出打印(false?0:x)
那么我得到的是
y
,那么为什么在这种情况下编译器不解释为
int

121
是字符
y
的整数表示形式。由于您在表达式中提供了
i
,编译器将其解释为对
System.out.print(int)
的调用,而不是
System.out.print(char)


请注意,更改为
System.out.print(false?(char)i:y)
打印
y

121是y的ASCII代码,正如您声明的i为整数一样,编译器也将y解释为int变量。因此,打印y的ASCII值。写入系统输出打印(false?(char)i:y)将打印y

对您的问题的简短回答是,打印的值基于条件表达式计算结果的类型

所以你们的问题可以归结为,为什么条件表达式的类型不同于

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

要回答这个问题,我们需要看一下

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

  • 布尔条件表达式
  • 数值条件表达式
  • 引用条件表达式
由于
int
char
都可转换为数值类型,因此根据此规则,表达式是数值条件表达式的一个示例:

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

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

  • 独立形式(§15.2)的表达式,其类型可转换为数字类型(§4.2,§5.1.8)
鉴于此,确定整个表达式类型的规则如下所示:

15.25.2。数字条件表达式

数值条件表达式是独立表达式(§15.2)

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

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

  • 如果第二个和第三个操作数中的一个是基元类型T,而另一个的类型是对T应用装箱转换(§5.1.7)的结果,则条件表达式的类型是T

  • 如果其中一个操作数的类型为byte或byte,而另一个操作数的类型为short或short,则条件表达式的类型为short

  • 如果其中一个操作数为T类型,其中T为字节、短字符或字符,而另一个操作数为int类型的常量表达式(§15.28),其值可在T类型中表示,则条件表达式的类型为T

  • 如果其中一个操作数为T类型,其中T为字节、短字符或字符,而另一个操作数为int类型的常量表达式,其值可在U类型中表示,U类型是对T应用取消装箱转换的结果,则条件表达式的类型为U

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

请注意,二进制数字升级执行值集转换(§5.1.13)并可能执行取消装箱转换(§5.1.8)

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

但是,当您传入一个变量而不是常量时,您将使用最后一条规则,即“……条件表达式的类型是第二个和第三个操作数的提升类型。”

如果您看一下,它将对类型提升的规则进行如下描述:

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

  • 如果任何操作数是引用类型,则它将进行取消装箱转换(§5.1.8)

  • 加宽基元转换(§5.1.2)用于转换以下规则指定的一个或两个操作数:

    • 如果其中一个操作数的类型为double,则另一个操作数将转换为double

    • 否则,如果其中一个操作数的类型为float,则另一个操作数将转换为float

    • 否则,如果其中一个操作数的类型为long,则另一个操作数将转换为long

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

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

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