Это струнные вещи;)

Прочитав руководство по программированию OCP для Java SE 7, я думаю, что все это небольшие, но важные ключевые моменты, которые каждый Java-разработчик должен знать о классе String.

String - это класс, поэтому вы можете создать строковый объект с помощью new String ();
В любой строке каждый символ является 16-битным Unicode.

Строка неизменна. Термин неизменяемый здесь относится к объекту String, который создается и назначается некоторой ссылочной переменной.

/**
* Here myString is a reference variable that holds the reference to * the actual String object created in memory.
*/
String myString = new String();

Итак, вы можете изменить значение ссылочной переменной myString в любое время, поскольку это не фактический объект.

Когда вы создаете объект String, он создается внутри памяти кучи Java, и ссылочная переменная просто имеет ссылку на него.

String x = "ab";
x = "cd";
print(x); //output will be cd

Итак, после присвоения нового значения cd старое значение ab находится в памяти, оно называется потерянный объект.
Теперь вы можете легко связать почему String называется неизменяемым, поскольку мы не можем изменить исходный объект «ab».

Теперь подумайте об этих операциях, выполняемых над String

String x= "Java";
x.concat(" Facts");
print(x); 
//Output : Java

В приведенном выше фрагменте кода, когда мы выполняем операцию concat, в памяти будет 2 объекта
1. Java
2. Факты о Java
, но , поскольку у нас нет никаких ссылок на вновь созданные «Факты о Java», он станет потерянным объектом. и x по-прежнему относится к Java.

Теперь, если вы уже заметили, мы можем создавать объекты String следующими способами

String s = new String("myString");
or
String s = new String();
s = "some other string"
or even better
String s = "more better string"

В Java есть концепция строкового литерала, вот пример литерала

"Yes! I am a string literal"

JVM выделяет другое пространство памяти, известное как пул строковых констант, и сохраняет все литералы в пуле, и всякий раз, когда он находит какой-либо строковый литерал во время компиляции, он проверяет, есть ли идентичный строковый литерал уже существует в пуле, если какие-либо совпадения найдены, новый литерал не будет создан, просто ссылка будет добавлена ​​к старому литералу.

Итак, здесь s и s2 оба относятся к одному и тому же строковому литералу «Привет!». Вот как в большом проекте, если существует много одинаковых строк. Память не будет жаловаться.

Но если вы явно создаете новый объект, вызывая new String (), он создаст новый объект внутри java heap, несмотря на то, что идентичная строка уже существует в пуле или нет.

В общем, вы всегда должны использовать строковые литералы, чтобы компилятор мог оптимизировать ваш код.

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

Сравнение в строке

String first = "hello"
String second = "hello"
print(first == second) // true
String first = "hello"
String second = new String("hello")
print(first == second) //false

Как и в первом примере, оба строковых литерала одинаковы, поэтому == возвращает true, но во втором примере, когда мы взяли new String (), он возвращает false.

Чтобы сравнивать строковые значения, а не ссылочные, существует метод .equals (), который сравнивает фактические значения.

String first = new String("hello")
String second = new String("hello")
print(first.equals(second)) //true

Это все мелочи, но важные о строках, спасибо :)