Подтвердить что ты не робот

В чем разница между изменяемой и неизменяемой строкой в ​​java

Как мне известно,

измененная строка может быть изменена и неизменяемая строка не может быть изменена.

Здесь я хочу изменить значение String следующим образом:

String str="Good";
str=str+" Morning";

и другим способом,

StringBuffer str= new StringBuffer("Good");
str.append(" Morning");

В обоих случаях я пытаюсь изменить значение str. Может ли кто-нибудь сказать мне, какая разница в обоих случаях и дать мне четкое представление о изменяемых и неизменяемых объектах.

4b9b3361

Ответ 1

Случай 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 не является.

Ответ 2

В чем разница между изменяемой и неизменяемой строкой в ​​java

существует неизменяемое, изменяемое.

Ответ 3

В Java все строки неизменяемы. Когда вы пытаетесь изменить String, то, что вы действительно делаете, это создание нового. Однако, когда вы используете StringBuilder, вы фактически изменяете содержимое, а не создаете новый.

Ответ 4

Java String неизменяемы.

В первом примере вы меняете ссылку на String, присваивая ей значение еще двух Strings в сочетании: str + " Morning".

Наоборот, a StringBuilder или StringBuffer могут быть изменены с помощью своих методов.

Ответ 5

Когда вы говорите 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);
}

Ответ 6


Строка в 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

Посмотрим по-разному, что мы можем создать String в 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 являются строковыми литералами, которые создаются в пуле констант String
  • str3, str4 и str5 являются объектами String, которые помещаются в память кучи
  • str1 = "Hi!"; создает "Hi!" в пуле констант String, и он полностью отличается от "Hey!", который str1 ссылается ранее.

Здесь мы создаем строковый литерал или объект String. Оба разные, я бы предложил вам прочитать следующую запись, чтобы больше узнать об этом.

В любом объявлении 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. Но на самом деле этот массив будет инициализирован один раз и во всей программе, он останется тем же.

Почему StringBuffer изменен?

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

Ответ 8

Mutable Objects: Если у вас есть ссылка на экземпляр объекта, содержимое этого экземпляра может быть изменено

Неизменяемые объекты: Если у вас есть ссылка на экземпляр объекта, содержимое этого экземпляра не может быть изменено

Поясним это с помощью примера:

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. Содержимое объекта не изменилось; мы отбросили экземпляр и изменили нашу ссылку на новую с новым содержимым.

Ответ 9

Я изменил код william с выходными комментариями для более понятного

   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(), хотя ur меняет значение str в changeStr(), оно влияет только на эту функцию, но в основной функции это значение не изменен, но это не в случае StringBuffer..

В StringBuffer измененное значение влияет как глобальное.

Следовательно, String является неизменным и StringBuffer является изменяемым...

В Простой, независимо от того, что изменено на String Object, будет влиять только на эту функцию. Перейдя в String Pool. но не Изменен...

Ответ 10

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

Ответ 11

Mutable означает, что вы сохраняете одну и ту же ссылку в переменной и изменяете ее содержимое, но неизменяете, вы не можете изменять содержимое, но объявить новую ссылку содержит новую и старую значение переменной

Ex Неизменяемый → Строка

String x = "value0ne";// adresse one x += "valueTwo"; //an other adresse {adresse two} адрес на изменение памяти кучи.

Mutable → StringBuffer - StringBuilder StringBuilder sb = new StringBuilder(); sb.append("valueOne"); // adresse One sb.append("valueTwo"); // adresse One

sb все еще в том же адресе Я надеюсь, что этот комментарий поможет