簡體   English   中英

Java中字符串創建的時間

[英]Time of Strings Creation in Java

我正在為J2ME設備編寫一個應用程序,並且非常關心不必要的字符串創建。 由於使用Strings是內置的,即沒有必要明確地創建它們,我不確定我是否理解它。

例如,返回一個String(只是使用雙引號)在返回時創建字符串,即如果我有幾個返回語句返回不同的字符串,則只會創建一個字符串。 是對的嗎?

此外,當使用字符串打印帶有異常的消息時,如果不拋出異常,這些字符串永遠不會被創建,對吧?

抱歉打擾你這樣一個新手問題。

到目前為止,我對你收到的答案一點也不確定。 如果你只是返回一個字符串文字,例如

return "foo";

然后將這些值嵌入到類文件中。 JVM確保只創建該字符串的一個實例(來自文字) - 但我不認為在加載類本身時,它不會保證它不會為類中的所有常量創建字符串。

然后再次,因為字符串只會被創建一次 (每個字符串常量),這不太可能是一個問題。

現在,如果您的代碼實際上更像是這樣:

return "foo" + new Date();

就是動態創建一個字符串 - 但只有在實際命中了return語句時才會創建它。

答案比其他一些答案建議的要復雜一些。

  • 在加載類時,將創建一次與源代碼中的字符串文字對應的String值。 此外, 這些字符串會自動“實現”,這意味着如果相同的字面值出現在任何類的多個位置,則只保留一個字符串副本。 (任何其他副本, 如果它們被創建將收集垃圾。)

  • 當應用程序調用new String(...) ,當它計算字符串連接表達式(即+運算符)時,或者當它調用在引擎蓋下創建字符串的許多庫方法之一時,將創建一個新的String。

那么回答你的問題:

1 - 以下內容實際上根本不會創建一個String。 而是它將返回在加載類時創建的String:

        return "some string";

2 - 以下將創建兩個字符串。 首先它將調用someObject.toString(),然后它將與文字連接,以給出另一個String。

        return "The answer is :" + someObject;

3 - 以下內容不會創建字符串; 見1。

        throw new Exception("Some message");

4 - 以下將在執行時創建兩個字符串; 見2。

        throw new Exception(someObject + "is wrong");

(實際上,3和4掩蓋了這樣一個事實,即創建異常會導致捕獲當前線程的調用堆棧的詳細信息,並且這些細節包括每個幀的方法名稱,類名和文件名。字符串時未指定表示這些東西實際上是創建的,或者它們是否被實現。因此,創建Exception對象的行為可能會觸發創建多個字符串。)

是。 如果通過調用構造函數創建實例的表達式或不執行(對於字符串)評估文字的表達式,則不會創建任何內容。

而且,編譯器會進行一些優化。 基於字符串文字的字符串對象將只創建一次並在之后實現。 像這兒:

 
 
 
  
  public String getHello() { return "Hello"; } public void test() { String s = getHello(); // String object created String t = getHello(); // no new String object created }
 
  


JVMS有不同的“意見”:

在以下情況下可能會隱式創建新的類實例:

  • 加載包含String文字的類或接口可能會創建一個新的String對象(第2.4.8節)來表示該文字。 如果已經創建了一個String對象來表示該文字的上一個匹配項,或者如果已在表示與該文字相同的字符串的String對象上調用了String.intern方法,則可能不會發生這種情況。

所以上面的例子是不正確的(我每天都在學習新東西)。 VM在類加載期間檢查是否必須創建"Hello" (如果尚未存在,則將創建String實例)。

所以現在我的理解是,VM為每個唯一的String文字創建一個String實例(在字節代碼級別上!),無論它是否被使用。

在字節代碼級別上,因為編譯器可以優化字符串文字與一個文字的連接,如:表達式"one"+"two"將被編譯為"onetwo"

只有在調用時才會創建字符串(和其他對象)。

那么回答你的問題:

  1. 是的,只會創建返回的String
  2. 是的,只有在拋出異常時,才會創建此String

這里的主要概念是,在您的邏輯流使解釋器執行該行編譯代碼之前,任何String的堆分配(您所說的創建)或任何對象的更一般術語都不會發生。

暫無
暫無

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

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