Строковые объекты и куча - PullRequest
       11

Строковые объекты и куча

0 голосов
/ 04 октября 2011

Я готовлюсь к экзамену SCJP, и у меня есть набор вопросов, над которыми я работаю.

Ответ на один вопрос, в котором я не уверен, и надеялся, что кто-то здесь сможет помочь мне уложить этот вопрос в постель.

Вот вопрос,

Дано:

11. public String makinStrings() {
12.    String s = "Fred";
13.    s = s + "47";
14.    s = s.substring(2, 5);
15.    s = s.toUpperCase();
16.    return s.toString();
17. }

Сколько String объектов будет создано при вызове этого метода?

A. 1
B. 2
C. 3
D. 4
E. 5
F. 6

Заранее благодарю за любую помощь. Я очень ценю это.

Ответы [ 4 ]

7 голосов
/ 04 октября 2011

Давайте пройдемся по строке.

Строка 11

Легкое начало, здесь нет созданных строк.

Строка 12

Мы присваиваем строку "Fred" s. Хотя похоже, что здесь создана строка, эта строка будет жить в постоянном пуле. JVMS раздел 2.17.6 Создание экземпляров нового класса гарантирует, что объекты для строковых литералов будут самое позднее будут созданы при загрузке окружающего класса, что определение до вызова метода . Поэтому в этой строке не создаются новые строковые объекты.

Строка 13

Ссылка на буквальную строку "47", которая снова будет создана статически (как указано выше). Однако есть также вызов оператора +, который создаст новую строку для хранения результата конкатенации. Итак, это первая созданная строка.

Строка 14

Метод substring действительно создает новую строку. Он разделяет базовый символьный массив со своим родителем - и поэтому почти не требует дополнительной памяти - но поскольку строки являются неизменяемыми, для каждого различного строкового представления требуется отдельный объект String. (Это, вероятно, ошибка - мой первый инстинктивный ответ был «ах, строка, созданная подстрокой, является особенной», но, конечно, ей все равно нужно создать новый объект).

Строка 15

Как и выше - представление в верхнем регистре отличается, поэтому для хранения результата необходимо создать новую строку.

Строка 16

Strings переопределяет метод toString() на простой return this - следовательно, дополнительная строка не создается.

Счет на дверях

По моим подсчетам, это три объекта String, созданные во время этого метода (два из этих объектов совместно используют один и тот же базовый символьный массив и два ранее существующих объекта, на которые ссылаются строковые литералы).

2 голосов
/ 04 октября 2011

На самом деле можно было бы превратить весь метод в одну константу. Это возможно, но компилятору не разрешено это делать. Следовательно, есть 3 строки, созданные с использованием 2 из пула констант.

  • Fred47
  • ed4 (примечание: используя тот же символ поддержки [], что и Fred47)
  • ED4

2 и 3 довольно просты, так как компилятору не разрешено оптимизировать вызовы этого метода, но String изменилась. Sting.toString () возвращает только this, поэтому новой строки тоже нет. Но давайте посмотрим на строку 13, используя разобранный байт-код (javap -c ваш друг здесь):

public java.lang.String makinStrings();
  Code:
   0:   ldc #16; //String Fred
   2:   astore_1
   3:   new #18; //class java/lang/StringBuilder
   6:   dup
   7:   aload_1
   8:   invokestatic    #20; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
   11:  invokespecial   #26; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
   14:  ldc #29; //String 47
   16:  invokevirtual   #31; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   19:  invokevirtual   #35; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       // SNIP
}

Как видите, "Fred" и "47" загружаются из пула констант (ldc), чтобы заполнить StringBuilder, который в итоге станет String (StringBuilder.toString ()).

Таким образом, получается 2 постоянных строки плюс 3 вновь созданных строки на вызов метода.

0 голосов
/ 04 октября 2011

это создаст 5 объектов строки

string является неизменным классом, поэтому для каждой новой строки он создает объект.

Пример

  1. public String makinStrings () {
    1. String s = "Fred"; (эта строка создает 1 --- строка Фреда)
    2. s = s + "47"; (эта строка создает 2- 47 строк + 3- Fred47)
    3. s = s подстрока (2, 5); (эта строка создать 4-е изд4)
    4. s = s.toUpperCase (); (эта строка создает 5-ED4)
    5. return s.toString ();

Итак, по моему мнению, он создаст 5 объектов

0 голосов
/ 04 октября 2011

Я бы сказал 3: те, что в строках 12, 13 и 15.

Причина, по которой строка 14 (подстрока) не создает новый объект, заключается в том, что String работает внутренним образом.Из-за необходимой оптимизации подстроки (все, включая компилятор, зависит от подстроки), класс String имеет два указателя на начало и конец строки.Выполнение подстроки только перемещает эти указатели и не «копирует» объект в новый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...