Является ли" новая строка () " неизменной?



Я некоторое время изучал строку Java. Следующие вопросы основаны на следующих сообщениях



строка Java является специальной
неизменяемость строки в java





  1. неизменяемости:
    Теперь, исходя из неизменности, класс String был спроектирован так, что значения в общий бассейн может быть повторно использован в других местах / переменных. Это хорошо, если String был создан как



    String a = "Hello World!";
    Однако, если я создаю строку типа



    String b = new String("Hello World!");
    почему это тоже непреложно? (или это так?). Поскольку у этого есть выделенная память кучи, я должен быть в состоянии изменить это, не затрагивая любую другую переменную. Итак, по замыслу, была ли какая-либо другая причина, почему String в целом считается неизменным? Или мое предположение неверно?




  2. второе, что я хотел спросить о общий пул строк. Если я создам строковый объект как



    String c = "";
    создается ли пустая запись в пуле?




есть ли какой-либо пост уже на них? Если да, то может ли кто-нибудь поделиться ссылкой?

626   15  

15 ответов:

new String() - Это выражение, которое производит String ... и String неизменна, независимо от того, как он произведен.

(прошу если new String() изменчиво или нет бессмысленно. Это программный код, а не значение. Но я так понимаю, что на самом деле вы имели в виду не это.)


если я создаю строковый объект как String c = ""; создается ли пустая запись в пуле?

да; то есть, запись создается для пустая строка. Нет ничего особенного в пустом String.

(чтобы быть педантичным, вход в бассейн для "" создается задолго до выполнения кода. Фактически, он создается при загрузке кода ... или, возможно, даже раньше.)


Итак, мне хотелось узнать, является ли новый объект кучи неизменяемым ...

да. Но неизменность является фундаментальным свойством Объект string. Все String объекты.

вы видите,String API просто не дает любой методы изменения a String. Так что (кроме некоторых опасных и глупых1 трюки с использованием отражения), вы не можете мутировать a String.

и если да, то с какой целью?.

причина в том, что Java String разработан как неизменяемый класс простоты. Это делает его легче писать правильно программ, и читать / рассуждать о коде других людей, если класс core string предоставляет неизменяемый интерфейс. (Или, по крайней мере, это обоснование этого проектного решения, как я понимаю.)

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

нет. Это более фундаментально, чем это. Просто, все String объекты являются неизменными. Там не является ли сложным частным случаем рассуждение, необходимое для понимания этого. Это просто > > есть

для записи, если вы хотите изменяемый "строковый" объект в Java, вы можете использовать StringBuilder или StringBuffer. Но это разные типы строк.


1 - причина, по которой эти трюки (IMO) опасны и глупы, заключается в том, что они влияют на значения строк, которые потенциально разделяются другими частями вашего приложения через пул строк. Это может вызвать хаос ... таким образом, следующий парень, поддерживающий ваш код, имеет мало шансов на отслеживание.

строка неизменна независимо от того, как она создается

1) короткий ответ:да,new String() - Это тоже непреложно.

потому что все возможно изменяемые операции (типа replace,toLowerCase etcetra), что вы выполняете на 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 Oracle:

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

и снова:

строковые буферы поддерживают изменяемые строки. Потому Что Строка объекты неизменяемы они могут быть общими.

вообще говоря: "все примитивные" (или связанные) объекты неизменны (пожалуйста, примите мое отсутствие формализм.)

связанный пост на переполнение стека:

о пуле объектов: пул объектов-это оптимизация 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-короткий ответ: да будет пустым.

созданные строки всегда будут неизменяемыми независимо от того, как они создаются.

ответы на ваши вопросы:

  1. единственная разница:
    Когда строка создается как...{String a = "Hello World!";} затем только один объект получает.
    И когда он создается как -- {String b = new String("Hello World!");} затем два объекта создаются. Первый, потому что вы использовали 'new' ключевое слово и второй из-за строка собственность.

  2. Да, конечно. В пуле будет создана пустая запись.

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

тождественно, целое число является неизменяемым, потому что нет никакого способа изменить его.

не имеет значения, как вы его создаете.

неизменность не является особенностью 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

    Ничего не найдено.