簡體   English   中英

當我做“”+1我得到一個字符串 - 為什么

[英]When I do “”+1 I get a String - Why

請首先理解我完全理解當我使用“”+ int時Java會返回一個String。

我真正不確定的是在內存方面究竟發生了什么。 java執行此轉換的確切方式。 我的意思是非常深入,不是'自動拳擊'或類似的東西:)

我希望有更深入理解的人可以解釋到底做了什么。

實際上,對於“”+ 1,編譯器創建一個String常量String,其值為“1”並將其放入常量池中 - 因此在運行時不會執行任何操作。

如果你有“”+ x(其中x是一個int變量),你得到以下字節碼(來自當前的JDK 1.6):

  0:   new     #2; //class java/lang/StringBuilder
  3:   dup
  4:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
  7:   ldc     #4; //String
  9:   invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  12:  aload_0
  13:  arraylength
  14:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  17:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  20:  astore_1
  21:  return

所以它創建一個StringBuilder,將“”附加到它,然后將int值附加到它,然后在StringBuilder實例上調用toString。

在StringBuilder.append(int)方法中,它最終調用Integer.getChars(包私有方法)。

您可以在JDK src.zip(或src.jar)副本中查找append和getChars的源代碼。

+被視為字符串連接,因為字符串位於操作數的一側 - 這也適用於1+"" 因此, 1被隱式轉換為字符串"1"""與其連接,從而產生""+"1" => "1"

這有時被用作將整數變量轉換為String的快速而骯臟的方式,例如

String s = "" + myInt;

但“正確”的方法是:

String s = Integer.toString(myInt);

或者:

String s = String.valueOf(myInt);

編輯:

為了澄清,編譯器進行此確定並插入將在執行串聯之前將整數轉換為字符串的代碼。

基本上編譯器看到:

String s = "" + myInt;

並有效地創建相當於的字節碼

String s = "" + String.valueOf(myInt)

雖然它可能在實踐中優化連接。

Java語言規范15.18.1.1字符串轉換

可以通過字符串轉換將任何類型轉換為String類型。

首先將基本類型T的值x轉換為引用值,就像將其作為參數提供給適當的類實例創建表達式一樣:

  • 如果T是布爾值,則使用new Boolean(x)。
  • 如果T是char,則使用new Character(x)。
  • 如果T是byte,short或int,則使用new Integer(x)。
  • 如果T很長,則使用新的Long(x)。
  • 如果T是float,則使用new Float(x)。
  • 如果T為double,則使用new Double(x)。

然后通過字符串轉換將此引用值轉換為String類型。

現在只需要考慮參考值。 如果引用為null,則將其轉換為字符串“null”(四個ASCII字符n,u,l,l)。 否則,執行轉換就好像通過調用沒有參數的引用對象的toString方法一樣; 但是如果調用toString方法的結果為null,則使用字符串“null”。

toString方法由原始類Object定義; 許多類都覆蓋它,特別是Boolean,Character,Integer,Long,Float,Double和String。

編輯這些引用中的一些是為了相關性,並且可以增加重點。

JLS 15.18.1字符串連接運算符+

如果只有一個操作數表達式是String類型,則在另一個操作數上執行字符串轉換以在運行時生成字符串。 結果是對String對象的引用,該對象是兩個操作數字符串的串聯。

JLS 15.18.1.1字符串轉換

  • 首先將基本類型T的值x轉換為引用值, 就像將其作為參數提供給適當的類實例創建表達式一樣:
    • 如果T是byteshortint ,則使用new Integer(x)
  • 現在只需要考慮參考值。 轉換的執行就像調用toString()方法一樣。

根據該規范, "" + i被評估為好像它被寫為"" + new Integer(i).toString() 該操作是字符串連接,這會產生一個字符串。

請注意上述段落中的“好像”一詞; 只有正確的行為被精確指定,但是如何在引擎蓋下完成它留給實現。

我現在在討論中省略的一些事情是:

  • null始終轉換為"null"
  • 內聯編譯時常量( JLS 15.28
  • 使用mutable StringBuffer / StringBuilder優化( JLS 15.18.1.2

“a”+“b”只是StringBuilder.append(“a).append(”b“)的語法糖,因為你可以.append(1)並自動將它轉換為你所看到的String 。

暫無
暫無

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

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