Неизменность строк в Java - PullRequest
205 голосов
/ 12 октября 2009

Рассмотрим следующий пример.

String str = new String();

str  = "Hello";
System.out.println(str);  //Prints Hello

str = "Help!";
System.out.println(str);  //Prints Help!

Теперь в Java объекты String неизменны. Тогда как же объекту str может быть присвоено значение «Помогите!». Разве это не противоречит неизменности строк в Java? Кто-нибудь может объяснить мне точную концепцию неизменности?

Edit:

Ok. Теперь я понимаю, но только один дополнительный вопрос. А как насчет следующего кода:

String str = "Mississippi"; 
System.out.println(str); // prints Mississippi 

str = str.replace("i", "!"); 
System.out.println(str); // prints M!ss!ss!pp! 

Означает ли это, что два объекта создаются снова ("Миссисипи" и "M! Ss! Ss! Pp!"), А ссылка str указывает на другой объект после метода replace()?

Ответы [ 25 ]

0 голосов
/ 22 августа 2016

Или вы можете попробовать:

public class Tester
{
public static void main(String[] args)
{
 String str = "Mississippi"; 
 System.out.println(str); // prints Mississippi 
 System.out.println(str.hashCode());

 str = str.replace("i", "!"); 
 System.out.println(str); // prints M!ss!ss!pp! 
 System.out.println(str.hashCode());
 }
 }

Это покажет, как изменяется хэш-код.

0 голосов
/ 24 апреля 2015

Для тех, кто интересуется, как нарушить неизменность String в Java ...

Код

import java.lang.reflect.Field;

public class StringImmutability {
    public static void main(String[] args) {
        String str1 = "I am immutable";
        String str2 = str1;

        try {
            Class str1Class = str1.getClass();
            Field str1Field = str1Class.getDeclaredField("value");

            str1Field.setAccessible(true);
            char[] valueChars = (char[]) str1Field.get(str1);

            valueChars[5] = ' ';
            valueChars[6] = ' ';

            System.out.println(str1 == str2);
            System.out.println(str1);
            System.out.println(str2);           
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }
}

Вывод

true
I am   mutable
I am   mutable
0 голосов
/ 31 августа 2015

В Java к объектам обычно обращаются по ссылкам. В вашем фрагменте кода str есть ссылка, которая сначала присваивается «Hello» (автоматически созданный объект или извлекается из постоянного пула ), а затем вы назначаете другой объект «Help!» к той же ссылке. Следует отметить, что ссылка такая же и изменена, но объекты разные. Еще одна вещь в вашем коде, вы получили доступ к трем объектам,

  1. Когда вы вызываете new String ().
  2. Когда вы назначили «привет».
  3. Когда вы назначили «помощь!».

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

Надеюсь, это поможет.

0 голосов
/ 06 февраля 2016

Неизменность Я могу сказать, что вы не можете изменить саму строку. Предположим, у вас есть строка x, значение которой равно «abc». Теперь вы не можете изменить строку, то есть вы не можете изменить любой символ / символы в "abc".

Если вам нужно изменить какой-либо символ / ы в строке, вы можете использовать массив символов и изменить его или использовать StringBuilder.

String x = "abc";
x = "pot";
x = x + "hj";
x = x.substring(3);
System.out.println(x);

char x1[] = x.toCharArray();
x1[0] = 's';
String y = new String(x1);
System.out.println(y);

Выход:

hj
sj
0 голосов
/ 05 января 2016

Строка является неизменной . Это означает, что мы можем изменить только ссылку .


String a = "a";
System.out.println("String a is referencing to "+a); // Output: a

a.concat("b");
System.out.println("String a is referencing to "+a); // Output: a

a = a.concat("b");
System.out.println("String a has created a new reference and is now referencing to "+a); // Output: ab
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...