2017-10-12 165 views
3

我們假設我們有一個StringBuilder和一個double。現在想要追加雙。如果double可以表示爲Integer(例如3.0,5.0等),我想將它添加爲Integer,否則爲double。Java三元運算符不工作?

第一種方法來實現,這是:

StringBuilder sb = new StringBuilder(); 
double d = 3.5; 

if (d % 1 == 0) sb.append((int) d); 
else sb.append(d); 

System.out.println(sb.toString()); 

這工作還是不錯的,當d3.0 3將被追加,如果d3.5 3.5將被追加。

現在我想與三元運營商短期內做到這一點:

StringBuilder sb = new StringBuilder(); 
double d = 3.5; 

sb.append(d % 1 == 0 ? (int) d : d); 

System.out.println(sb.toString()); 

所以現在我有一個問題,每一次,如果雙是3.03.5它將被添加作爲雙重價值!只有當我理論上投在truefalse它的作品......但每一次,這不是我想要的。這裏有什麼問題?爲什麼三元操作員不工作?

+0

您應該使用'DecimalFormat(「0。#」)'來擺脫尾部零,而不是轉換爲'int'。 –

回答

2

此行爲的原因是具有三元運算符的表達式具有明確定義的類型。 JLS詳細描述瞭如何評估這種類型,但粗略地說,它是冒號前的表達式類型和冒號後的表達式類型的最小上限。

例如,如果bbooleaniintddouble,那麼b ? i : d類型是double,因爲double是最小上界的intdouble。當您在StringBuilder上撥打append(b ? i : d)時,將獲得版本appenddouble參數。同樣的事情發生在你的情況下,d % 1 == 0 ? (int) d : d

4

此行爲記錄在JLS-15.25中。 Conditional Operator ? : :

如果操作數中的一個是類型T,其中T是字節,短,或炭的,而另一個操作數是int類型的常量表達式(§15.28),其值是在類型T表示的,然後條件表達式的類型爲T

當編寫

(a > b) ? 'a' : 65 

所述第二類型被轉換爲炭。

通過JLS,它解釋了其他情況下的行爲(同樣的方法)。

+0

奇怪的是,如果我評估'd%1 == 0? (int)d:d'(其中d = 3)返回「3」。但隨後附加「3.0」。但這可能是Eclipse的一件事。 –

1

在基本數字上使用三元運算符時,第二個和第三個操作數受二進制數字提升的影響。在你的情況下,int被鑄造爲double。這在JLS #15.25中指定。

1

方法StringBuilder.append()對於不同類型的參數有許多過載。使用哪種方法重載是編譯時決定。在這種情況下,三元運算符的結果只有一種類型,即intdouble - double

if語句的情況下,編譯器根據分支使用正確的append()方法過載。

0

我認爲編譯器認爲sb.append(d % 1 == 0 ? (int) d : d)sb.append(double),否則sb.append((int) d)sb.append(int)

0

數值條件表達式是獨立表達式(§15.2)。

如果第二和第三個操作數具有相同的類型,則認爲是條件表達式的類型:

類型數值條件表達式如下確定。

如果第二個和第三個操作數中的一個是原始類型T,而另一個的類型是對T應用裝箱轉換(第5.1.7節)的結果,則條件表達式的類型爲T.

如果其中一個操作數的類型爲byte或Byte,另一個的類型爲short或Short,則條件表達式的類型很短。

如果其中一個操作數的類型是T,其中T是字節,短或char,另一個操作數是類型爲int的常量表達式(第15.28節),其值可用T類型表示,則類型條件表達式是T.

如果其中一個操作數是T類型,其中T是Byte,Short或Character,另一個操作數是類型爲int的常量表達式,其值可以在U類型中表示是將拆箱轉換應用到T的結果,那麼條件表達式的類型爲U.

否則,對操作數類型應用二進制數字提升(第5.6.2節),並且條件表達式的類型是第二個和第三個操作數的提升類型。

這些類型被轉換爲它們相應的基元,這就是所謂的拆箱。 如果一個操作數是一個常量int(在拆箱前不是整數),其值可以在另一個類型中表示,則該int操作數將轉換爲另一個類型。 否則,較小的類型轉換爲下一個較大的類型,直到兩個操作數具有相同的類型。轉換命令是:

字節 - >短 - > INT - >長 - >浮 - >雙

炭 - > INT - >長 - >浮 - >雙

最終整個條件表達式獲取其第二個和第三個操作數的類型。