Страницы

Поиск по вопросам

воскресенье, 8 декабря 2019 г.

Неизменямость строк в Java

#java #строки


В книге П. Ноутона, Г. Шилдта  "Java 2. Наиболее полное руководство." сказано:

Кроме того, нужно понять, что объекты типа String неизменяемы. Если String-объект
создан, то его содержимое не может быть изменено. Хотя данное утверждение похоже на
серьезное ограничение, однако это не так по двум причинам:
  если нужно изменить строку, то всегда можно создать её новую модифицированную копию;

  Java определяет класс просмотра (peer class) для String, называемый StringBuffer,  
  который позволяет строкам стать изменяемыми, так что все нормальные манипуляции со 
  строками все еще доступны в Java. (StringBuffer описан в Части 2 этой книги).


Я решил проверить данное утверждение и написал программу, изменяющую String-объект:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package teststring0;

/**
 *
 * @author Asus
 */
public class TestString0 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
    String str="Тестовая строка 1";
    System.out.println(str);
    str="Тестовая строка 2";
    System.out.println(str);

    }
}

которая в NetBeans выдает следующий результат:
run:
Тестовая строка 1
Тестовая строка 2
ПОСТРОЕНИЕ УСПЕШНО ЗАВЕРШЕНО (общее время: 0 секунд)

Что авторы имели ввиду под неизменяемостью String-объектов (видимо я неправильно
понимаю авторов книги)?    


Ответы

Ответ 1



Под неизменяемостью, или иммутабельностью (immutability) подразумевается невозможность изменения содержимого объекта после его создания. Следующий код лишь заменяет ссылку на объект, не модифицируя самого объекта: str="Тестовая строка 2"; Строковый литерал из правой части выражения представляет собой заранее созданный объект.

Ответ 2



Смотрите. В Java есть объекты, и есть ссылки на объекты. Когда вы пишете String s = "hello funny world"; ваше s -- ссылка на объект-строку. Сам объект никогда не меняется. Чтобы "изменить" строку, вам придётся создать новую строку, и присвоить s ссылку на эту новую строку. Все функции, манипулирующие строками, возвращают именно новую строку, а вы просто заменяете ссылку на старую строку ссылкой на новую. Пример: String s1 = "123"; String s2 = s1; // обе ссылки указывают на одну и ту же строку String s3 = "456"; // другая строка s1 = s1.concat(s3); // изменили ссылку, создалась новая строка, и s1 ссылается // на неё System.out.print(s1); // печатает новую строку: "123456" System.out.print(s2); // печатает старую строку: "123", в s2 осталась // старая ссылка

Ответ 3



На самом деле содержимое объекта класса String можно поменять с помощью reflection, но с некоторыми ограничениями. Только делается это совсем не так, как пишете вы.

Ответ 4



Дополню немного @Flammable Что авторы имели ввиду под неизменяемостью String-объектов (видимо я неправильно понимаю авторов книги)? проверить можно способом System.err.println(str.substring(0, 10)); // произвели операцию над строкой System.err.println(str); // вывели строку, но она не изменилась метод вернет новую строку, так как str - не поменяется, что будет видно, по логу

Ответ 5



ИМХО , авторы имели ввиду что класс String объявлен как final и от него нельзя унаследоваться, нельзя переписать методы. да в общем ничего нельзя. фундаментальность java _ [хехЪ] линк на исходник The String class represents character strings. All string literals in Java programs, such as "abc", are implemented as instances of this class. Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared. For example: public final class String implements java.io.Serializable, Comparable, CharSequence{...}

Комментариев нет:

Отправить комментарий