What is the purpose of the expression "new String(...)" in Java?
Какова цель выражения "новая строка (...)" в Java?
Просматривая онлайн-примеры кода, я иногда сталкивался с присвоением строковой константы объекту String с помощью оператора new .
Например:
String s; ... s = newString("Hello World");
Это, конечно, по сравнению с
s = "Hello World";
Я не знаком с этим синтаксисом и понятия не имею, какова будет цель или эффект. Поскольку строковые константы обычно хранятся в пуле констант, а затем в любом представлении, которое JVM имеет для работы со строковыми константами, будет ли что-нибудь вообще размещено в куче?
Переведено автоматически
Ответ 1
Единственное место, где вы можете подумать, что хотите new String(String), - это принудительно создать отдельную копию внутреннего массива символов, как в
small=newString(huge.substring(10,20))
Однако, к сожалению, такое поведение недокументировано и зависит от реализации.
Я был поражен этим, когда считывал большие файлы (некоторые размером до 20 Мбайт) в строку и разделял ее на строки постфактум. В итоге я получил все строки для строк, ссылающихся на char[], состоящие из всего файла. К сожалению, это непреднамеренно сохранило ссылку на весь массив для нескольких строк, которые я удерживал в течение более длительного времени, чем обработка файла - я был вынужден использовать new String(), чтобы обойти это, поскольку обработка 20 000 файлов очень быстро потребляла огромное количество оперативной памяти.
Единственный независимый от реализации способ сделать это:
Для этого, к сожалению, необходимо скопировать массив дважды, один раз для toCharArray() и один раз в конструкторе String .
Должен быть документированный способ получения новой строки путем копирования символов существующей; или документация String(String) должна быть улучшена, чтобы сделать ее более явной (там есть подтекст, но он довольно расплывчатый и открытый для интерпретации).
Ошибка предположения о том, чего в документе не указано
В ответ на комментарии, которые продолжают поступать, обратите внимание, какой была реализация Apache Harmony new String():
Это верно, там нет копии базового массива. И все же, он по-прежнему соответствует документации по строкам (Java 7), поскольку он:
Инициализирует вновь созданный объект String таким образом, чтобы он представлял ту же последовательность символов, что и аргумент; другими словами, вновь созданная строка является копией строки аргумента. Если не требуется явная копия оригинала, использование этого конструктора не требуется, поскольку строки неизменяемы.
Основной частью является "копия строки аргумента"; в нем не сказано "копия строки аргумента и базового массива символов, поддерживающего строку".
Будьте осторожны, чтобы программировать на основе документации, а не однойреализации.
Ответ 2
Единственный раз, когда я нашел это полезным, - это при объявлении переменных блокировки:
В этом случае инструменты отладки, такие как Eclipse, будут показывать строку при перечислении того, какие блокировки поток в данный момент удерживает или ожидает. Вы должны использовать "новую строку", т. Е. Выделить новый строковый объект, потому что в противном случае общий строковый литерал может быть заблокирован в каком-либо другом несвязанном коде.
Ответ 3
Строка s1="foo"; литерал будет отправлен в StringPool, а s1 будет ссылаться.
Строка s2 = "foo"; на этот раз он проверит, доступен ли литерал "foo" в StringPool или нет, поскольку сейчас он существует, поэтому s2 будет ссылаться на тот же литерал.
Строка s3 = новая строка ("foo"); сначала в StringPool будет создан литерал "foo", затем с помощью конструктора string arg будет создан строковый объект, т. е. "foo" в куче из-за создания объекта с помощью оператора new, затем s3 будет ссылаться на него.
Строка s4= новая строка ("foo"); такая же, как s3
итак, System.out.println(s1==s2); //true из-за буквального сравнения.
и System.out.println(s3==s4);// false из-за сравнения объектов (s3 и s4 создаются в разных местах кучи)
Ответ 4
Единственная утилита для этого конструктора, описанная Software Monkey и Ruggs, похоже, исчезла из JDK7. В классе String больше нет offset поля, и substring всегда использует
Arrays.copyOfRange(char[] original, int from, int to)