2016-05-19 38 views
2

Java是一種強類型語言。因此,編譯代碼中的錯誤更少,代碼更慢,代碼更易讀。因此,需要明確的類型轉換,這部分是明確的。Java類型轉換。邏輯背後(字符串),.toString()和「」+ int

是這些片段之間的區別:

(String)myInt // obviously doesn't compile 
Integer.toString(myInt) 
"" + myInt 

它是純粹出於歷史原因,還是有一些背後的含義是什麼?
哪種方法比較合適?

+2

實際上,在Java的類型系統是健全的/足夠的情況下,類型* casting *是你不應該做的一件事。 –

+0

在這種情況下,什麼是(字符串)? – Stepan

回答

6

如前所述,(String) myInt是一個類型轉換。你可以在基元內或在對象層次中向上投射。由於int是一個原語,String是一個對象,所以我們有一個問題。即使Autoboxing也無法解決這個難題,因爲IntegerString不能保持繼承關係。因此,(String) myInt導致編譯錯誤是完全合理的。

Integer.toString(myInt)"" + myInt的語義是相同的。但具體情況則不同。

執行Integer.toString(myInt)時,會構造一個新的String,其中包含字符串表示形式myInt

當執行"" + myInt,首先建立一個全球性的String的常數,其數值""(這是由JVM做,你沒有看到這個)。詞法分析器要求+右側的String,因爲它發現+左側的String。對於原語,JVM「知道」如何將它們轉換爲String。對於對象,調用toString()。由於Object具有此方法,並且每個類都(至少隱式地)從Object派生,因此每個對象都保證有一個toString()方法。這是第二個String構建。由於Strings are immutable,JVM可能會創建第三個String,這表示前兩個String的拼接,即。

結語:
然後,在執行時,JIT編譯器觸發,其中大部分可能無關緊要,因爲兩種變體的JIT優化版本可能看起來相同。或不。或者也許只是有時候。 JIT搞笑的東西。那麼到底它更是一個比表現個人風格的問題:)


這實際上是一個謊言。當寫

String s1 = ""; 
String s2 = ""; 
System.out.println(s1 == s2); 

將觀察的結果是true,而false預期。這是由於JVM爲所有String常量創建池以節省一些內存。

JVM「識別」something + "" == "" + something == something並因此不創建第三個String的可能性很大。我沒有測試也沒有研究過。

4

我傾向於更喜歡String.valueOf(int),我自己,但是有多條路徑可以到達那裏。

一般情況下,如果你轉換intString孤立,你想Integer.toString(int)String.valueOf(int),或類似的。

"" + myInt將明顯高於上述(雖然它通常並不重要),低效率的:它編譯爲創建一個新的StringBuilder,然後追加""它,然後追加int它(它調用的一個上面的方法將其首先轉換爲字符串),然後從StringBuilder獲取String。所以雖然你可能把它作爲整體連接操作的一部分,但它本身就很差。

您的(String)示例不起作用:您無法將int投射到String,您將收到編譯時「不兼容類型」錯誤。

3

這是一個語言功能, 「正式」 重載+操作,使得

"" + myInt 

,好像它是被編譯:

new StringBuilder().append("").append(myInt).toString(); 

StringBuilder#append()(最終)調用String.valueOf()渲染myInt

此功能的完成大概是因爲如果他們不這樣做,沒有人會使用該語言 - 這太痛苦了。

+0

重載+運算符 - 這解釋了機制。 – Stepan

2

(String) - 這僅適用於字符串,所以如果你有這樣的:

Object test = "test"; 
String test2 = (String) test; 

它將工作(因爲Object測試將String類型)。

如果你有這樣的事情:

Integer test = new Integer(2); 
String test2 = (String) test; 

你得到ClassCastException

Integer.toString(myInt) 

這是它做什麼:

public static String toString(int i) { 
     if (i == Integer.MIN_VALUE) 
      return "-2147483648"; 
     int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); 
     char[] buf = new char[size]; 
     getChars(i, size, buf); 
     return new String(0, size, buf); 
    } 

它只是被燒焦把你的號碼串字符。

"" + myInt 

這會告訴你想加入的東西作爲字符串編譯器,而不是兩個數字(因爲字符串是第一個,它會與加盟串去)。 myInt將變成字符串,或者如果它是一個對象,它將從中調用toString()方法。

此外,請確保您閱讀JVM中的字符串池,以瞭解它將在此處執行的操作。在這種情況下,最終可能會創建大量臨時字符串(如果您有很多+;請使用StringBuilder避免這種情況)。

2

首先,讓我們比較(String)valval.toString()

在這些兩個語句的主要區別在於,鑄造是由編譯器製成toString()方法由程序員通常被實現。也就是說,只有當值擴展到String時,才能投射,並且您可以實現任何類別的toString()toString()就像任何其他方法一樣工作,沒有什麼(幾乎)特別的。我們來看看""+int。我個人認爲這是反模式,因爲它被編譯成非常有效的代碼。很多無用的對象被創建;簡而言之:結果類似於使用StringBuilder手動連接少數字符串文字。此外,在像""+varvar這樣的陳述中,不會延伸String,toString()隱式調用。

我希望這很清楚。