Вопрос по string, bytecode, object, stringbuilder, java – Сколько объектов создано

6

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

Пример 1:

<code>String s = "a";
s = s + "b";
s = s + "c";        
</code>

Пример 2:

<code>StringBuilder sb = new StringBuilder("a");
sb.append("b");
sb.append("c");
</code>

По моему мнению, Ex 1 создаст 5, а Ex 2 создаст 4 объекта.

Пример 1 генерирует это:String s = "a"; s = (new StringBuilder(String.valueOf(s))).append("b").toString(); s = (new StringBuilder(String.valueOf(s))).append("c").toString(); System.err.println(s);, Похоже, что Javac не оптимизирует это (по крайней мере, в Java 6) Guillaume Polet
@Thihara: нет, если компилятор Javac (а не JIT) попадет туда первым. Greg Kopff
В первом примере будет создан 1 объект, поскольку компилятор может его оптимизировать. Greg Kopff
Javac оптимизирует это? Amir Afghani
Это должно быть сделано, если это было: & quot; a & quot; + & quot; b & quot; + "с". Я удивлен, что другой случай тоже не оптимизирован. Ну да ладно ... Смотрите:nicklothian.com/blog/2005/06/09/on-java-string-concatenation Greg Kopff

Ваш Ответ

4   ответа
-1

и среды выполнения). Даже на наличие конкретных опций оптимизации или нет. И, конечно же, версия реализации (и, неявно, JLS, с которой она совместима). Так что лучше говорить в терминах минимумов и максимумов. На самом деле это упражнение дает лучшее

Для Ex1 минимальное количество объектов равно 1 (компилятор понимает, что задействованы только константы, и создает только код дляString s= "abc" ; ). Максимум может быть любым, в зависимости от реализации, но разумная оценка равна 8 (также приводится в другом ответе как число, полученное при определенной конфигурации).

Для Ex2 минимальное количество объектов - 2. Компилятор не может знать, заменили ли мы StringBuilder на пользовательскую версию с другой семантикой, поэтому он не будет оптимизирован. Максимум может быть около 6 для чрезвычайно экономной памяти реализации StringBuilder, которая расширяет основуchar[] массив один символ за раз, но в большинстве случаев это будет 2 тоже.

Компилятор производит код дляString s = "abc";', но это не создает объект при выполнении, поэтому минимум фактически равен нулю.
6

На моей машине первый пример создает 8 объектов:

String s = "a";
s = s + "b";
s = s + "c";
two objects of type String; two objects of type StringBuilder; four objects of type char[].

С другой стороны, второй пример:

StringBuffer sb = new StringBuffer("a");
sb.append("b");
sb.append("c");

создает 2 объекта:

one object of type StringBuilder; one object of type char[].

Это использует JDK 1.6u30.

Постскриптум Чтобы сделать сравнение справедливым, вы, вероятно, должны позвонитьsb.toString() в конце второго примера.

Кажется довольно глупым проводить различие междуchar[] и этоString абстракция в языке высокого уровня, таком как Java: P. Но я согласен, что это правильно (не глупо с вашей стороны ... просто глупо в таком глупом примере, как этот).
это зависит от машины / компилятора?
@GuillaumePolet: конечноchar[] это объект. Все массивы Java есть. Если вы мне не верите, попробуйтеnew char[0].getClass()или увидетьstackoverflow.com/questions/2009210/…
@AlexLockwood: Возможно, в некоторой степени зависит от JDK, хотя я был бы весьма удивлен, если бы существовала большая изменчивость в последних JDK.
@AlexLockwood: я действительно считаю, что очень важно учитывать суб-объекты (такие какchar[]в этом примере). Без этого подсчеты в значительной степени бессмысленны: всегда можно обернуть произвольное количество сложности в один объект и утверждать, что существует только один (верхний уровень)new.
4

javap -c). Пример 1 создает дваStringBuilder объекты (см. строку № 4) и дваString объекты (см. строку № 7), в то время как пример 2 создает одинStringBuilder объект (см. строку № 2).

Обратите внимание, что вы также должны принятьchar[] объекты во внимание (так как массивы являются объектами в Java).String а такжеStringBuilder оба объекта реализованы с использованием базовогоchar[], Таким образом, пример 1 создаетeight объекты и пример 2 создаетtwo объекты.

Пример 1:

public static void main(java.lang.String[]);
  Code:
   0:   ldc             #2; //String a
   2:   astore_1
   3:   new             #3; //class java/lang/StringBuilder
   6:   dup
   7:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   10:  aload_1
   11:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   14:  ldc             #6; //String b
   16:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   19:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   22:  astore_1
   23:  new             #3; //class java/lang/StringBuilder
   26:  dup
   27:  invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   30:  aload_1
   31:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   34:  ldc             #8; //String c
   36:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   39:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   42:  astore_1
   43:  return   
}

Пример 2:

public static void main(java.lang.String[]);
  Code:
   0:   new             #2; //class java/lang/StringBuilder
   3:   dup
   4:   ldc             #3; //String a
   6:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
   9:   astore_1
   10:  aload_1
   11:  ldc             #5; //String b
   13:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   16:  pop
   17:  aload_1
   18:  ldc             #7; //String c
   20:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   23:  pop
   24:  return  
}
У меня есть небольшое сомнение. , оракулы здесьdocs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html  говорит об этом при добавлении: & quot; public StringBuilder append (Object obj) Добавляет строковое представление аргумента Object. Общий эффект такой, как если бы аргумент был преобразован в строку с помощью метода String.valueOf (Object), а затем символы этой строки были добавлены к этой последовательности символов. & Quot; Не означает ли это, что объекты будут созданы для строковых литералов.
5

Пример 1 создает 8 объектов:

String s = "a"; // No object created
s = s + "b"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String)
s = s + "c"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String)

Пример 2 создает 2 объекта:

StringBuffer sb = new StringBuffer("a"); // 1 StringBuffer + 1 char[] (in SB)
sb.append("b"); // 0
sb.append("c"); // 0

Честно говоря, я не знал, что new char [] на самом деле создал объект в Java (но я знал, что они были созданы). Спасибо AIX за указание на это.

Downvoter, не могли бы вы высказать свое мнение?
Он / она мог запустить процедуру тестирования в другой версии JDK и получить другие результаты.

Похожие вопросы