В чем разница между изменяемой и неизменной строкой в Java
Насколько мне известно,
изменяемая строка может быть изменена, а неизменяемая строка не может быть изменена.
Здесь я хочу изменить значение String следующим образом:
String str="Good";
str=str+" Morning";
и другой способ,
StringBuffer str= new StringBuffer("Good");
str.append(" Morning");
В обоих случаях я пытаюсь изменить значение str
, Может кто-нибудь сказать мне, в чем разница в обоих случаях, и дать мне четкую картину изменчивых и неизменных объектов.
12 ответов
Случай 1:
String str = "Good";
str = str + " Morning";
В приведенном выше коде вы создаете 3 String
Объекты.
- "Хорошо" это входит в Струнный пул.
- "Утро" также входит в Струнный пул.
- "Доброе утро" создано путем объединения "Доброго" и "Утреннего". Этот парень идет в кучу.
Примечание. Строки всегда неизменны. Нет такой вещи, как изменяемая строка. str
это просто ссылка, которая в конечном итоге указывает на "Доброе утро". Вы на самом деле, не работаете над 1
объект. у тебя есть 3
отчетливый String
Объекты.
Случай 2:
StringBuffer str = new StringBuffer("Good");
str.append(" Morning");
StringBuffer
содержит массив символов. Это не то же самое, что String
, Приведенный выше код добавляет символы в существующий массив. Эффективно, StringBuffer
изменчив, его String
представление не.
В чем разница между изменяемой и неизменной строкой в Java
неизменяемые существуют, изменчивые нет.
В Java все строки неизменны. Когда вы пытаетесь изменить String
То, что вы действительно делаете, это создание нового. Тем не менее, когда вы используете StringBuilder
вы фактически изменяете содержимое, а не создаете новое.
Джава String
с неизменны.
В первом примере вы меняете ссылку на String
тем самым присваивая ему значение двух других Strings
комбинированный: str + " Morning"
,
Наоборот, StringBuilder
или же StringBuffer
может быть изменено с помощью его методов.
- Изменчивый :- Изменчивый
- Неизменный:- Не изменяемый
Строка в Java неизменна. Однако, что означает быть изменчивым в контексте программирования - это первый вопрос. Рассмотрим следующий класс,
public class Dimension {
private int height;
private int width;
public Dimenstion() {
}
public void setSize(int height, int width) {
this.height = height;
this.width = width;
}
public getHeight() {
return height;
}
public getWidth() {
return width;
}
}
Теперь после создания экземпляра Dimension
мы всегда можем обновить его атрибуты. Обратите внимание, что если какой-либо атрибут, в другом смысле состояния, может быть обновлен, например, для класса, то он называется изменяемым. Мы всегда можем сделать следующее,
Dimension d = new Dimension();
d.setSize(10, 20);// Dimension changed
d.setSize(10, 200);// Dimension changed
d.setSize(100, 200);// Dimension changed
Давайте посмотрим, как мы можем создать строку в Java.
String str1 = "Hey!";
String str2 = "Jack";
String str3 = new String("Hey Jack!");
String str4 = new String(new char[] {'H', 'e', 'y', '!'});
String str5 = str1 + str2;
str1 = "Hi !";
// ...
Так,
str1
а такжеstr2
строковые литералы, которые создаются в константном пулеstr3
,str4
а такжеstr5
являются строковыми объектами, которые помещаются в память кучиstr1 = "Hi!";
создает"Hi!"
в константе String, и это совершенно другая ссылка, чем"Hey!"
которыйstr1
ссылка ранее.
Здесь мы создаем строковый литерал или строковый объект. Оба они разные, я бы посоветовал вам прочитать следующий пост, чтобы больше узнать об этом.
В любом объявлении String общеизвестным является то, что он не изменяется, но создается или перемещается в другое.
String str = "Good"; // Create the String literal in String pool
str = str + " Morning"; // Create String with concatenation of str + "Morning"
|_____________________|
|- Step 1 : Concatenate "Good" and " Morning" with StringBuilder
|- Step 2 : assign reference of created "Good Morning" String Object to str
Как String стал неизменным?
Это неизменное поведение, значит, назначенное значение не может быть обновлено другим способом. Класс String внутренне содержит данные в массиве символов. Кроме того, класс создан, чтобы быть неизменным. Взгляните на эту стратегию определения неизменяемого класса.
Сдвиг ссылки не означает, что вы изменили ее значение. Было бы изменчиво, если вы можете обновить массив символов, который находится за сценой в классе String. Но в действительности этот массив будет инициализирован один раз, и во всей программе он останется прежним.
Почему StringBuffer изменчив?
Как вы уже догадались, класс StringBuffer сам по себе изменчив, так как вы можете напрямую обновлять его состояние. Как и String, он также содержит значение в символьном массиве, и вы можете манипулировать этим массивом различными методами, например, добавлением, удалением, вставкой и т. Д., Которые напрямую изменяют массив значений символов.
Когда ты сказал str
, вы должны быть осторожны, что вы имеете в виду:
Вы имеете в виду переменную
str
?или вы имеете в виду объект, на который ссылается
str
?
В вашем StringBuffer
Например, вы не меняете значение str
и в вашем String
Например, вы не изменяете состояние String
объект.
Самый острый способ почувствовать разницу будет примерно так:
static void change(String in) {
in = in + " changed";
}
static void change(StringBuffer in) {
in.append(" changed");
}
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("value");
String str = "value";
change(sb);
change(str);
System.out.println("StringBuffer: "+sb);
System.out.println("String: "+str);
}
В Java все строки являются неизменяемыми (невозможно изменить). Когда вы пытаетесь изменить строку, вы действительно создаете новую.
Следующими способами мы можем создать строковый объект
Использование строкового литерала
Strung str="java";
Используя новое ключевое слово
Strung str = new String("java");
Использование массива символов
char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };
String helloString = new String (helloArray);
приходя к неизменности String, просто означает неизменяемый или неизменяемый
Давайте возьмем один пример
Я инициализирую значение строкового литерала с
String s="kumar";
Ниже я собираюсь отобразить десятичное представление адреса местоположения, используя hashcode()
System.out.println(s.hashCode());
Простая печать значения строки
System.out.println("value "+s);
Хорошо, на этот раз я инициализирую значение "kumar" для s1
String s1="kumar"; // what you think is this line, takes new location in the memory ???
Хорошо, давайте проверим, отобразив хеш-код объекта s1, который мы создали
System.out.println(s1.hashCode());
хорошо, давайте проверим код ниже
String s2=new String("Kumar");
System.out.println(s2.hashCode()); // why this gives the different address ??
Хорошо, проверьте этот код ниже, наконец
String s3=new String("KUMAR");
System.out.println(s3.hashCode()); // again different address ???
ДА, если вы видите, что строки 's' и 's1' имеют одинаковый хеш-код, потому что значения, удерживаемые с помощью 's' и 's1', совпадают с 'kumar'
Давайте рассмотрим String 's2' и 's3', эти два хеш-кода Strings кажутся разными в том смысле, что они оба хранятся в разных местах, потому что вы видите, что их значения различны.
поскольку хэш-код s и s1 одинаков, поскольку эти значения одинаковы и хранятся в одном и том же месте.
Пример 1: попробуйте код ниже и анализируйте построчно
public class StringImmutable {
public static void main(String[] args) {
String s="java";
System.out.println(s.hashCode());
String s1="javA";
System.out.println(s1.hashCode());
String s2=new String("Java");
System.out.println(s2.hashCode());
String s3=new String("JAVA");
System.out.println(s3.hashCode());
}
}
Пример 2: попробуйте код ниже и анализируйте построчно
public class StringImmutable {
public static void main(String[] args) {
String s="java";
s.concat(" programming"); // s can not be changed "immutablity"
System.out.println("value of s "+s);
System.out.println(" hashcode of s "+s.hashCode());
String s1="java";
String s2=s.concat(" programming"); // s1 can not be changed "immutablity" rather creates object s2
System.out.println("value of s1 "+s1);
System.out.println(" hashcode of s1 "+s1.hashCode());
System.out.println("value of s2 "+s2);
System.out.println(" hashcode of s2 "+s2.hashCode());
}
}
Хорошо, давайте посмотрим, в чем разница между изменяемым и неизменным.
изменяемый (он изменяется) и неизменный (он не может измениться)
public class StringMutableANDimmutable {
public static void main(String[] args) {
// it demonstrates immutable concept
String s="java";
s.concat(" programming"); // s can not be changed (immutablity)
System.out.println("value of s == "+s);
System.out.println(" hashcode of s == "+s.hashCode()+"\n\n");
// it demonstrates mutable concept
StringBuffer s1= new StringBuffer("java");
s1.append(" programming"); // s can be changed (mutablity)
System.out.println("value of s1 == "+s1);
System.out.println(" hashcode of s1 == "+s1.hashCode());
}
}
Есть еще вопросы? пожалуйста, напишите на...
Его очень легко объяснить в этой связи с классом setter и getter, который является изменяемым, в то время как класс только с getter является неизменным. Вот подробности. http://latest-tutorial.com/2014/11/14/difference-mutable-immutable-objects-java/
Изменяемые объекты: если у вас есть ссылка на экземпляр объекта, содержимое этого экземпляра может быть изменено
Неизменяемые объекты: если у вас есть ссылка на экземпляр объекта, содержимое этого экземпляра не может быть изменено
Давайте разберемся с этим на примере:
String myString = new String( "old String" );
System.out.println( myString );
myString = new String( "new String" );
System.out.println( myString );
Выход из этого:
old String
new String
Теперь мы обнаруживаем, что значение, отображаемое переменной myString, изменилось. Мы определили неизменные объекты как неспособные изменить стоимость, так что же происходит? Давайте еще раз расширим пример, чтобы посмотреть ближе к переменной myString.
String myString = new String( "old String" );
String myCache = myString;
System.out.println( "equal: " + myString.equals( myCache ) );
System.out.println( "same: " + ( myString == myCache ) );
myString = "not " + myString;
System.out.println( "equal: " + myString.equals( myCache ) );
System.out.println( "same: " + ( myString == myCache ) );
Результат выполнения этого:
equal: true
same: true
equal: false
same: false
Это показывает, что переменная myString ссылается на новый экземпляр класса String. Содержимое объекта не изменилось; мы отказались от экземпляра и изменили нашу ссылку на новую с новым содержанием.
Изменяемая переменная - это переменная, значение которой может измениться на месте, тогда как в неизменяемой переменной изменение значения не произойдет. Изменение неизменяемой переменной перестроит ту же переменную.
Изменяемый означает, что вы сохраните ту же ссылку на переменную и измените ее содержимое, но неизменяемой вы не можете изменить содержимое, но вы объявите, что новая ссылка содержит новое и старое значение переменной
Бывшийнеизменный -> Строка
String x = "value0ne";// adresse one
x += "valueTwo"; //an other adresse {adresse two}
адрес на куче памяти меняется.
Изменяемый -> StringBuffer - StringBuilderStringBuilder sb = new StringBuilder();
sb.append("valueOne"); // adresse One
sb.append("valueTwo"); // adresse One
СБ все еще в том же адресе, я надеюсь, что этот комментарий поможет
Я изменил код Уильям с выходными комментариями для лучшего понимания
static void changeStr(String in) {
in = in+" changed";
System.out.println("fun:"+in); //value changed
}
static void changeStrBuf(StringBuffer in) {
in.append(" changed"); //value changed
}
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("value");
String str = "value";
changeStrBuf(sb);
changeStr(str);
System.out.println("StringBuffer: "+sb); //value changed
System.out.println("String: "+str); // value
}
В приведенном выше коде посмотрите на значение str в main() и changeStr(), хотя при изменении значения str в changeStr () оно влияет только на эту функцию, но в основной функции значение не изменяется, но это не в случае StringBuffer..
В StringBuffer измененное значение влияет как глобальное.
следовательно, String неизменен, а StringBuffer изменчив...
В Простом все, что вы изменили на String Object, повлияет только на эту функцию, перейдя в String Pool. но не изменилось...