Является ли" новая строка () " неизменной?
Я некоторое время изучал строку Java. Следующие вопросы основаны на следующих сообщениях
строка Java является специальной
неизменяемость строки в java
неизменяемости:
Теперь, исходя из неизменности, класс String был спроектирован так, что значения в общий бассейн может быть повторно использован в других местах / переменных. Это хорошо, еслиStringбыл создан как
String a = "Hello World!";
Однако, если я создаю строку типа
String b = new String("Hello World!");
почему это тоже непреложно? (или это так?). Поскольку у этого есть выделенная память кучи, я должен быть в состоянии изменить это, не затрагивая любую другую переменную. Итак, по замыслу, была ли какая-либо другая причина, почемуStringв целом считается неизменным? Или мое предположение неверно?
второе, что я хотел спросить о общий пул строк. Если я создам строковый объект как
String c = "";
создается ли пустая запись в пуле?
есть ли какой-либо пост уже на них? Если да, то может ли кто-нибудь поделиться ссылкой?
15 ответов:
new String()- Это выражение, которое производитString... иStringнеизменна, независимо от того, как он произведен.(прошу если
new String()изменчиво или нет бессмысленно. Это программный код, а не значение. Но я так понимаю, что на самом деле вы имели в виду не это.)
если я создаю строковый объект как
String c = "";создается ли пустая запись в пуле?да; то есть, запись создается для пустая строка. Нет ничего особенного в пустом
String.(чтобы быть педантичным, вход в бассейн для
""создается задолго до выполнения кода. Фактически, он создается при загрузке кода ... или, возможно, даже раньше.)
Итак, мне хотелось узнать, является ли новый объект кучи неизменяемым ...
да. Но неизменность является фундаментальным свойством Объект string. Все
Stringобъекты.вы видите,
StringAPI просто не дает любой методы изменения aString. Так что (кроме некоторых опасных и глупых1 трюки с использованием отражения), вы не можете мутировать aString.и если да, то с какой целью?.
причина в том, что Java
Stringразработан как неизменяемый класс простоты. Это делает его легче писать правильно программ, и читать / рассуждать о коде других людей, если класс core string предоставляет неизменяемый интерфейс. (Или, по крайней мере, это обоснование этого проектного решения, как я понимаю.)идя по ответу, я понимаю, что другие ссылки на ту же переменную является одной из причин. Пожалуйста, дайте мне знать, если я прав в понимании этого.
нет. Это более фундаментально, чем это. Просто, все
Stringобъекты являются неизменными. Там не является ли сложным частным случаем рассуждение, необходимое для понимания этого. Это просто > > естьдля записи, если вы хотите изменяемый "строковый" объект в Java, вы можете использовать
StringBuilderилиStringBuffer. Но это разные типы строк.
1 - причина, по которой эти трюки (IMO) опасны и глупы, заключается в том, что они влияют на значения строк, которые потенциально разделяются другими частями вашего приложения через пул строк. Это может вызвать хаос ... таким образом, следующий парень, поддерживающий ваш код, имеет мало шансов на отслеживание.
строка неизменна независимо от того, как она создается
1) короткий ответ:да,
new String()- Это тоже непреложно.потому что все возможно изменяемые операции (типа
replace,toLowerCaseetcetra), что вы выполняете наStringне влияет на оригиналStringэкземпляр и возвращает вам новый экземпляр.вы можете проверить это в Javadoc для
String. Каждыйpublicспособ изStringто есть exposed возвращает новыйStringэкземпляр и не изменяет текущий экземпляр, на котором вы вызвали метод.это очень полезно в многопоточной среде, так как вам не нужно думать о изменчивости (кто-то изменит значение) каждый раз, когда вы проходите или доли
Stringвокруг.Stringможет легко быть наиболее часто используемым типом данных, поэтому дизайнеры благословили нас всех, чтобы не думать о изменчивости каждый раз и спас нас много боль.неизменяемость допускается пул строк или кэширование
именно из-за свойства неизменяемости был возможен внутренний пул строк, так как когда одно и то же строковое значение требуется в каком-то другом месте, то возвращается эта неизменяемая ссылка. Если
Stringбыло бы изменчиво, тогда было бы невозможно поделитьсяStrings, как это, чтобы сохранить память.неизменность строки была не из-за объединения, но неизменность имеет больше преимуществ прикрепленный к ему.
строка интернирования или объединения является примером Flyweight Design pattern
2) Да он будет интернирован, как и любой другой
StringпробелStringэто тоже столько жеStringкак и другиеStringэкземпляров.ссылки:
библиотеки Java сильно оптимизированы вокруг ограничения, что любой
Stringобъект является неизменяемым, независимо от того, как этот объект построен. Даже если вы создадите свойbС помощьюnew, другой код, который вы передаете этому экземпляру, будет рассматривать значение как неизменяемое. Это пример шаблона объекта Value, и все преимущества (потокобезопасность, отсутствие необходимости делать частные копии) применяются.пустая строка
""законноеStringобъект как все остальное, у него просто нет внутреннего содержимого, и поскольку все строки констант времени компиляции интернированы, я практически гарантирую, что некоторая библиотека времени выполнения уже вызвала ее добавление в пул.
1) неизменяемая часть не , потому что из бассейна; это просто делает бассейн возможным в первую очередь. Строки часто передаются в качестве аргументов другим функциям или даже совместно используются с другими потоками; создание неизменяемых строк было проектным решением, чтобы упростить рассуждение в таких ситуациях. Так что Да -
Strings в Java всегда неизменяемы, независимо от того, как вы их создаете (обратите внимание, что в java можно иметь изменяемые строки - просто не сStringкласс.)2) Да. Возможно. Я на самом деле не уверен на 100%, но это должно быть так.
это не совсем ответ на ваш вопрос, но если за ваш вопрос-это желание иметь изменяемые строки, которые вы можете манипулировать, вы должны проверить
StringBuilderкласс, который реализует многие из тех же самых методов, чтоStringимеет, но также добавляет методы для изменения текущего содержимого.как только вы построили свою строку таким образом, что вы довольны ею, вы просто вызываете
toString()на нем для того, чтобы преобразовать его в обычныйStringчто вы можете перейти к библиотечные процедуры и другие функции, которые принимают толькоStrings.и
StringBuilderиStringосуществляетCharSequenceинтерфейс, поэтому если вы хотите написать функции в своем собственном коде, которые могут использовать как изменяемые, так и неизменяемые строки, вы можете объявить их для любого
строки являются постоянными; их значения не могут быть изменены после того, как они создано.
и снова:
строковые буферы поддерживают изменяемые строки. Потому Что Строка объекты неизменяемы они могут быть общими.
вообще говоря: "все примитивные" (или связанные) объекты неизменны (пожалуйста, примите мое отсутствие формализм.)
связанный пост на переполнение стека:
- неизменяемость строк в Java
- является ли строка Java неизменяемой?
- на Java "передача по ссылке" и "передача по значению"?
- является ли строка Java действительно неизменяемой?
- строка является неизменяемой. Что именно это означает?
- в чем причина стоящая строка неизменяемая в java?
о пуле объектов: пул объектов-это оптимизация java, которая также не связана с неизменяемым.
string является неизменным, означает, что вы не можете изменить сам объект, независимо от того, как вы его создали.А что касается второго вопроса: да, он создаст запись.
на самом деле все наоборот.
[...] the
Stringкласс был разработан таким образом, что значения в общем пуле могут быть повторно использованы в других местах / переменных.нет,
Stringкласс является неизменяемым, так что вы можете безопасно ссылаться на его экземпляр, не беспокоясь о том, что он будет изменен из другой части вашей программы. Вот почему объединение возможно в первую очередь.так, рассмотрим это:
// this string literal is interned and referenced by 'a' String a = "Hello World!"; // creates a new instance by copying characters from 'a' String b = new String(a);теперь, что произойдет, если вы просто создадите ссылку на ваш вновь созданный
bпеременной?// 'c' now points to the same instance as 'b' String c = b;представьте, что вы проходите
c(или, более конкретно, объект, на который он ссылается) к методу в другом потоке и продолжить работу с тем же экземпляром в главном потоке. А теперь представьте, что было бы, если бы струны были изменчивы.почему это так?
если ничего кроме того, это потому, что неизменяемые объекты делают многопоточность намного проще и, как правило, даже быстрее. Если вы разделяете изменяемый объект (это будет любой объект с сохранением состояния, с изменяемыми частными/общедоступными полями или свойствами) между различными потоками, вам нужно проявлять особую осторожность, чтобы обеспечить синхронизированный доступ (мьютексы, семафоры). Даже при этом, вам нужно особое внимание, чтобы обеспечить атомарность во всех ваших операциях. Многопоточность-это сложно.
что касается производительности, отметим, что довольно часто копирование всей строки в новый экземпляр, чтобы изменить даже один символ, на самом деле быстрее, чем вызов дорогостоящего переключения контекста из-за конструкций синхронизации, необходимых для обеспечения потокобезопасного доступа. И, как вы уже упоминали, неизменность также предлагает возможности интернирования, что означает, что она действительно может помочь уменьшить использование памяти.
это вообще очень хорошая идея сделайте столько вещей неизменными, сколько сможете.
1) неизменяемость: строка будет неизменяемой, если вы создадите ее с помощью нового или другого способа по соображениям безопасности
2) Да в пуле строк будет пустая запись.
вы можете лучше понять концепцию, используя код
String s1 = new String("Test"); String s2 = new String("Test"); String s3 = "Test"; String s4 = "Test"; System.out.println(s1==s2);//false System.out.println(s1==s3);//false System.out.println(s2==s3);//false System.out.println(s4==s3);//trueнадеюсь, что это поможет ваш запрос. Вы всегда можете проверить исходный код для класса String в случае лучшего понимания ссылке : http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java
1- String и неизменяемые.Смотрите это:
является ли строка Java действительно неизменяемой?
Так что вы можете создать много способов.
2-короткий ответ: да будет пустым.
созданные строки всегда будут неизменяемыми независимо от того, как они создаются.
ответы на ваши вопросы:
единственная разница:
Когда строка создается как...{String a = "Hello World!";}затем только один объект получает.
И когда он создается как --{String b = new String("Hello World!");}затем два объекта создаются. Первый, потому что вы использовали 'new' ключевое слово и второй из-за строка собственность.Да, конечно. В пуле будет создана пустая запись.
строка является неизменяемой, потому что она не предоставляет вам средства для ее изменения. Это дизайн, чтобы избежать любого вмешательства (это окончательно, базовый массив не должен быть затронут ...).
тождественно, целое число является неизменяемым, потому что нет никакого способа изменить его.
не имеет значения, как вы его создаете.
неизменность не является особенностью
new, Это особенность классаString. У него нет мутаторных методов, поэтому он неизменен.
String A = "Test" String B = "Test"Теперь Строку
B called"тест".toUpperCase ()which change the same object into"тест", soAwill also be"тест "' что не желательно.
обратите внимание, что в вашем примере ссылка изменяется, а не объект, на который она ссылается, т. е.
bКак ссылка может быть изменена и ссылаться на новый объект. Но этот новый объект является неизменяемым, что означает, что его содержимое не будет изменено "после" вызова конструктора.вы можете изменить строку, используя
b=b+"x";илиb=new String(b);, и содержание переменнойaкажется, меняется, но не путайте неизменность ссылки (здесь переменнаяb) и объекта ссылаясь на (подумайте о указателях в C). Объект, на который указывает ссылка, останется неизменным после его создания.Если вам нужно изменить строку, изменив содержимое объекта (вместо изменения ссылки), вы можете использовать
StringBuffer, который является изменяемой версией строки.
Comments