Подтвердить что ты не робот

Ошибка в моделировании экзамена OCJP: сколько объектов действительно создано?

В симуляции для сертификации OCJP я нашел этот вопрос:

1. StringBuffer s1 = new StringBuffer("abc");
2. StringBuffer s2 = s1;
3. StringBuffer s3 = new StringBuffer("abc");

How many objects are created ?

Они утверждают, что правильный ответ равен 4, поскольку они указывают:

s1 is one object, s2 is another object, 
s3 is another object and "abc" is another String Object .

Но для меня это неправильно, и оно должно быть 3, потому что s1 и s2 - это один и тот же объект. Как вы думаете?

4b9b3361

Ответ 1

Вы правы, что ответ не 4 объекта.

Однако вопрос "сколько объектов создается" неоднозначен. Проблема в том, что один из трех объектов не создается при выполнении кода. В частности, объект String, соответствующий литералу "abc", фактически создается при загрузке кода. Когда этот код выполняется, создаются два объекта StringBuffer, и используется существующий объект String.

И на самом деле это сложнее, поскольку в момент загрузки класса возможно создание другого временного объекта String и затем отбрасывается после его интернирования;

  • Если литерал "abc" уже загружен в другой класс, то он будет использоваться.

  • Не указано, если реализация пула строк создает новую копию String, если она должна быть помещена в пул.

Если вопрос более точно не сформулирован, то нет единого правильного ответа. Лучшее, что вы можете сказать:

  • При запуске кода создаются два объекта StringBuffer.
  • Один или два объекта String создаются при загрузке кода.

Тогда возникает вопрос, следует ли считать частные char[] объекты, которые являются частью объектов StringBuffer и String. Это может увеличить количество объектов до 8.

Ответ 2

Да определенно 3 Object.both s1 и s2, ссылающиеся на одно и то же место. поэтому s1, s2 и "abc" являются объектами здесь. Может быть, лучше не следовать этой ссылке.

Ответ 3

КОРРЕКЦИЯ

Должно быть 3 объекта:

1. StringBuffer s1 = new StringBuffer("abc");

В памяти s1 и "abc" будут созданы два объекта. Это связано с тем, что строки интернированы, а литералы добавляются в пул памяти.

2. StringBuffer s2 = s1;

Здесь не будет создан объект, потому что s2 укажет на "abc", созданный как часть s1

3. StringBuffer s3 = new StringBuffer("abc");

Для s3 будет создан только один объект.

Ответ 4

Как насчет:

1. StringBuffer s1 = new StringBuffer("abc");

1 builder object + 1 char[] object + (1 Строковый литерал, если он создан)

2. StringBuffer s2 = s1;

Нет новых объектов.

3. StringBuffer s3 = new StringBuffer("abc");

1 builder объект + 1 char[] объект

A StringBuilder инкапсулирует поддержку char [] внутри, которая является объектом.

Как @StephenC говорит, что вопрос неоднозначен.

Ответ 5

3 или 4, в зависимости от реализации. Некоторые компиляторы создавали бы только один объект String для константы "abc" и ссылались бы на него столько раз, сколько необходимо, а другие компиляторы могли бы создать один объект на константу. AFAIK, это не было санкционировано всеми версиями спецификаций языков, и в будущем это может измениться.

Или больше, в зависимости от реализации StringBuffer (который мог бы активно создавать char [] и копировать строку инициализации, в отличие от ленивой реализации, которая откладывает это до тех пор, пока содержимое StringBuffer не будет действительно изменено). Опять же, это не должно регулироваться языком. И, BTW, массивы считаются Object для целей вопроса? А что, если реализация StringBuffer хранит информацию в структуре JNI? Что это значит как объекты? Я просто пытаюсь пересмотреть свою точку зрения о деталях реализации, не связанных с языком.

Тест не должен задавать такие вопросы, если только речь идет о конкретной реализации и/или версии JLS.

Совершенно ясно, что аргумент , который они дают для ответа 4, совершенно неверен. Назначение s2 не создает никакого нового объекта.