2013-04-02 4 views
6

Я и мой друг обсуждали на нитях, и мы застряли на этом:Сколько объектов String ..?

String str = "ObjectOne"+"ObjectTwo"; 

Он говорит, что общие три объект будет создан, и я говорю, один объект будет создан.

Его логика для 3 объектов: одна для «ObjectOne» и одна для «ObjectTwo», а третья - конкатенированная версия двух объектов String.

Моя логика одного объекта во время компиляции как строковые объекты будут каскадной в байт-код, как:

String str = "ObjectOneObjectTwo"; 

И во время выполнения только один объект будет создан таким образом. В чем же истина.

+0

был аналогичный вопрос здесь: http://stackoverflow.com/questions/15669067/fastest-way-of-converting-integer-to-string-in-java – msi

ответ

11

Если вы пишете (литералы или константы)

String str = "ObjectOne"+"ObjectTwo"; 

это эквивалентно

String str = "ObjectOneObjectTwo"; // compiler optimize it so one Object 
7

Вы можете найти это для себя с помощью инструмента javap разобрать код, чтобы увидеть, что компилятор из него. Предположим, у вас есть этот пример:

public class Example { 
    public static void main(String[] args) { 
     String s = "ObjectOne" + "ObjectTwo"; 
     System.out.println(s); 
    } 
} 

компилировать его, а затем разобрать его с javap -c Example. Результат:

Compiled from "Example.java" 
public class Example { 
    public Example(); 
    Code: 
     0: aload_0 
     1: invokespecial #1     // Method java/lang/Object."<init>":()V 
     4: return 

    public static void main(java.lang.String[]); 
    Code: 
     0: ldc   #2     // String ObjectOneObjectTwo 
     2: astore_1 
     3: getstatic  #3     // Field java/lang/System.out:Ljava/io/PrintStream; 
     6: aload_1 
     7: invokevirtual #4     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     10: return 
} 

Как вы видите, есть только один String объект, который содержит «ObjectOneObjectTwo». Итак, действительно, компилятор делает конкатенацию для вас во время компиляции.

+0

+1 для вас для самообучающегося примера. – Sajmon

-3
String str = "ObjectOne"+"ObjectTwo"; 

3 объекты будут созданы как

1- "ObjectOne"

2- "ObjectTwo"

3- "ObjectOneObjectTwo"

использование

StringBuffer tmp = new StringBuffer("ObjectOne"); 
tmp.append("ObjectTwo"); 
str = tmp.toString(); 
+0

hai, пожалуйста, найдите свою концепцию конкатенации строк до голосования вниз. Http: //javapapers.com/core-java/java-string-concatenation/ –

+1

'String fruit =" Apple "; fruit = fruit + «World»; это действительно создаст два объекта. Но 'String fruit =« Apple »+« World »;' создаст только один объект. OP задает вопрос о втором синтаксисе. – AmitG

1

Вы можете легко проверить это самостоятельно:

  1. собрать следующую программу:

    public static void main(String[] args) { 
        String str = "ObjectOne"+"ObjectTwo"; 
        System.out.println(str); 
    } 
    
  2. Осмотреть байт-код, испускаемый компилятором:

    javap.exe -v Test.class 
    

Для основного метода , это отпечатки:

public static void main(java.lang.String[]); 
    flags: ACC_PUBLIC, ACC_STATIC 

    Code: 
     stack=2, locals=2, args_size=1 
     0: ldc   #16     // String ObjectOneObjectTwo 
     2: astore_1  
     3: getstatic  #18     // Field java/lang/System.out:Ljava/io/PrintStream; 
     6: aload_1  
     7: invokevirtual #24     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     10: return   
     LineNumberTable: 
     line 6: 0 
     line 7: 3 
     line 8: 10 
     LocalVariableTable: 
     Start Length Slot Name Signature 
       0  11  0 args [Ljava/lang/String; 
       3  8  1 str Ljava/lang/String; 
} 

Как вы можете видеть, программа использует инструкцию byteecode ldc для обращения к одному, уже загруженному экземпляру строки (который загружается, когда Test.class). Поэтому во время выполнения этой строки не создается новый объект.

Компилятор required выполнить эту оптимизацию по спецификации языка Java:

Объект Строки вновь создается (§12.5), если выражение не является константным выражением во время компиляции (§15.28).

0
String str1 = "ObjectOne"; 
String str2 = "ObjectTwo"; 
str1 = str1+str2; 

В вышеописанном случае будут созданы три объекта.

Но когда вы определяете, как

String str = "ObjectOne"+"ObjectTwo"; 

тогда только один объект будет создан. Компилятор оптимизирует его.

0

Объект String неизменен.

String str = "ObjectOne"+"ObjectTwo"; 

     is same as 

    String str = "ObjectOneObjectTwo"; 

Под неизменным мы подразумеваем, что значение, хранящееся в объекте String, не может быть изменено. Тогда следующий вопрос, который приходит нам на ум: «Если String неизменен, то как я могу изменить содержимое объекта, когда захочу?». Ну, точнее, это не тот же объект String, который отражает изменения, которые вы делаете. Внутри создается новый объект String для внесения изменений.

Так предположим, что вы объявляете объект строки:

String myString = "Hello"; 

Далее вы хотите добавить «гость» в той же строке. Чем ты занимаешься?

myString = myString + " Guest"; 

Когда вы печатаете содержимое myString, выход будет «Hello Guest». Хотя мы использовали один и тот же объект (myString), внутри процесса был создан новый объект. Так что мистик будет ссылаться на «Привет Гость». Ссылка на привет проиграна.

String s1 = "hello"; //case 1 
    String s2 = "hello"; //case 2 

В случае 1 буквально s1 создается вновь и хранится в бассейне. Но в случае 2, буква s2 ссылается на s1, вместо этого он не будет создавать новый.

if (s1 == s2) System.out.println ("equal"); // печать равна

 String s= "abc"; //initaly s refers to abc 
     String s2 =s; //s2 also refers to abc 
     s=s.concat("def"); // s refers to abcdef. s no longer refers to abc. 

enter image description here

Смежные вопросы