簡體   English   中英

輸出與我的預期不同

[英]Output different from what i have expected

為何打印X88

public static void main(String [] args)
{
      char x = 'X';
      int i = 0;
      System.out.print(true  ? x : 0);
      System.out.print(false ? i : x);
}

在第一個print語句中,條件表達式的類型是char(即'X'),因為JLS第15.25部分(約為條件表達式的類型)適用於:

如果其中一個操作數是T類型,其中T是byte,short或char,另一個操作數是int類型的常量表達式,其值可以在類型T中表示,那么條件表達式的類型是T.

所以第一個語句打印“X”。

在第二個print語句中,該部分不適用,因為i 不是常量表達式。 相反,本節適用:

否則,二進制數字提升(第5.6.2節 )將應用於操作數類型,條件表達式的類型是第二個和第三個操作數的提升類型。 請注意,二進制數字促銷執行拆箱轉換(第5.1.8節)和值集轉換(第5.1.13節)。

二進制數字提升將char'X'轉換為int(88),第二個語句打印“88” - 因此“X88”的整體結果。

它在JLS的§15.25中有解釋。

否則,如果第二個和第三個操作數具有可轉換的類型(第5.1.8節)到數字類型,則有幾種情況:

這適用於兩個語句,因為char和int都是數字類型,因此5.1.8非常適用。 所以我們看下面的規則(摘錄):

[...]

  • 如果其中一個操作數是T類型,其中T是byte,short或char,另一個操作數是int類型的常量表達式,其值可以在類型T中表示,那么條件表達式的類型是T.

這適用於第一個,因為0是int類型的常量表達式。 T是, char ,這就是它打印為X的原因。

[...]

  • 否則,二進制數字提升(第5.6.2節 )將應用於操作數類型,條件表達式的類型是第二個和第三個操作數的提升類型。 請注意,二進制數字促銷執行拆箱轉換(第5.1.8節)和值集轉換(第5.1.13節)。

這適用於第二種,因為沒有別的。 :) §5.6.2中的相關規則很簡單:

否則,兩個操作數都將轉換為int類型。

'X'的Unicode代碼點是88。

對於第一個語句System.out.print(false ? x : 0); 編譯器認為您要打印一個char,因此0將被視為char(在編譯期間)。

當你做System.out.print(false ? i : x); 編譯器認為你要打印一個整數,所以它會嘗試將(加寬)'X'轉換為88的整數。

有趣的是,如果你嘗試這樣做:

System.out.print(true ? x : i);

由於i不能被視為一個字符(它需要縮小),它將打印88

這里有另一個令人沮喪的事情:

System.out.print(true  ? x : 65536);

這次在編譯時不能將值65536視為char(char的最大值為65535 [@See Character.MAX_VALUE]),因此它將被視為int,因此x也是如此。


總而言之,如果操作數之一是int而另一個是char,則有兩種可能的轉換:

  1. int縮小為char(精度損失)
  2. char擴展為int(不損失精度)

為了避免無用的損失,Java將選擇第二個選項。

當你做System.out.print(false ? x : 0); ,0在編譯時轉換為char(因為編譯器知道不會丟失精度)。


資源:

因為表達式false ? i : x false ? i : x被視為由編譯器返回一個整數。 由於您使用的是char因此'X'在ASCII中為88,因為它們是兼容的,所以它被視為整數。

就個人而言,我認為這里至少應該有一個編譯器警告。

在第二個三元組If中,參數必須是相同的類型,否則兩個中的一個是隱式轉換的。

在您的示例中,x從char轉換為int,而'X'的ASCII代碼為88。

其他人已經回答了為什么會這樣。

如果要打印X ,請將表達式值轉換回char

System.out.print((char)(false ? i : x)); // prints X

或者您也可以將ichar以便表達式的類型變為char

System.out.print(false ? (char)i : x); // prints X

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM