我在不可变字符串上写了下面的代码。

public class ImmutableStrings {

    public static void main(String[] args) {
        testmethod();
    }

    private static void testmethod() {
        String a = "a";
        System.out.println("a 1-->" + a);
        a = "ty";
        System.out.println("a 2-->" + a);
    }
}

输出:

a 1-->a  
a 2-->ty

这里变量a的值被改变了(尽管许多人说不可变对象的内容不能被改变)。但是说字符串是不可变的到底是什么意思呢?你能给我解释一下这个话题吗?

来源:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html


当前回答

在你的例子中,变量a只是一个字符串对象实例的引用。当你说a = "ty"时,你实际上并没有改变字符串对象,而是将引用指向string类的一个完全不同的实例。

其他回答

字符串是一个char[],包含一系列UTF-16代码单元,该数组的int偏移量和int长度。

为例。

String s

它为字符串引用创建空间。赋值复制周围的引用,但不修改这些引用所引用的对象。

你也应该意识到

new String(s)

并没有做任何有用的事情。它只是创建了另一个实例,支持的数组、偏移量和长度与s相同。很少有理由这样做,因此大多数Java程序员认为这是一种糟糕的做法。

Java双引号字符串,如“my string”,实际上是对内部string实例的引用,因此“bar”是对同一个string实例的引用,而不管它在代码中出现了多少次。


“hello”创建了一个被池化的实例,而新的String(…)创建了一个非池化的实例。尝试system . out。println((“hello”= =“你好 ") + "," + ( 新的字符串“hello”= =“你好 ") + "," + ( 新的字符串(“hello”)= =新的字符串(“hello”)));你应该看到真,假,假

String S1="abc";
S1.concat("xyz");
System.out.println("S1 is", + S1);
String S2=S1.concat("def");
System.out.println("S2 is", + S2);

这表明一旦创建了一个字符串对象,它就不能被更改。每次你需要创建new并放入另一个String。年代

Java字符串是不可变的,字符串将以对象的形式存储值。所以如果你赋值String a="a";它将创建一个对象,值存储在其中,如果你分配值a="ty"意味着它将创建另一个对象存储在其中的值,如果你想清楚地理解,检查字符串的has代码。

字符串是不可变的,这意味着,字符串对象的内容不能被改变,一旦它被创建。如果你想修改内容,那么你可以去StringBuffer/StringBuilder而不是String。StringBuffer和StringBuilder是可变类。

不可变对象是创建后状态不能修改的对象。

a = "ABC" <——immutable object。"a"保存对对象的引用。 并且,a = "DEF" <——另一个不可变对象,"a"现在保存着对它的引用。

一旦你分配了一个字符串对象,该对象就不能在内存中被改变。

总之,您所做的就是将“a”的引用更改为一个新的字符串对象。