我在java类中的方法中有一个字符串,如下所示
public void show(){
String s1;
s1 = "abc";
s1 = "def";
System.out.println(s1);
}
这里的输出是 def ,但由于String是不可变的,所以我不明白字符串s1在这里是不可变的,因为我可以从 abc 更改String s1内容 def 。
你可以让我理解这个吗?答案 0 :(得分:5)
你没有改变字符串;您更改了变量s1
,以便它引用不同的字符串。原字符串" abc"仍然存在且尚未修改(并且无法修改,因为字符串是不可变的)。
试试这个:
public void show() {
String s1 = "abc";
String s2 = s1;
System.out.println("s1 is same object is s2? = " + (s1 == s2));
s1 = "def";
System.out.println("s1 = " + s1);
System.out.println("s2 = " + s2);
}
请注意,将s1
设置为引用新字符串不会影响原始字符串,因此s2
仍会引用它。
答案 1 :(得分:2)
通过可变,你的意思是你有相同的对象,你可以修改它的状态(就像你的类有一个Date对象)。因此,不可变的恰恰相反。考虑Date类,我将它定义为:
Date date = new Date();//print it and you will get today's date
date.setTime(date.getTime() - 10days in millis);//print and see you changed your date by bask 10 days which you changed internal state (field) of Date
现在在您的示例中,您将新的字符串重新分配给s1
字符串,即将引用从一个字符串更改为另一个字符串。您没有更改内部字符数组,即String对象的字段。
答案 2 :(得分:2)
字符串 不可变表示您无法更改对象本身,但可以更改对象的引用。当你打电话
s1 = "abc";
s1 = "def";
,您实际上是将s1的引用更改为由字符串文字“def”创建的新对象。
S1只是对象的引用,它不是实际对象
试试这种方式
s1="abc";
s1.toUpperCase();
System.out.println(s1);
输出仍然
abc
由于s1.toUpperCase()
而不是更改 String s1 的内容,它会创建一个带有大写内容的新对象,但由于我们没有捕获返回的变量这就是输出仍然相同的原因
现在尝试使用
s1="abc";
s1=s1.toUpperCase();
System.out.println(s1);
现在输出
ABC
答案 3 :(得分:0)
如果您尝试创建字符串对象。内存将在堆上以及字符串池中创建。例如:String str = new String(" hello"); 对于变量str,将在堆上创建值为" hello"以及字符串"你好"将在字符串池中创建。 str是引用变量,它将引用" hello"在字符串池中。 现在,如果您尝试创建
String s1 =" hello&#34 ;;
这里s1是引用变量.String pool已经有值" hello"。所以s1会引用"你好"。
与此概念相同。 s1是引用变量。它首先引用" abc"在String池。然后它指的是" def"在字符串池。你没有对" abc"做出任何改变。或" def"在字符串池,因为它们是不可变的。如果你想为StringBuffer和StringBuilder创建可变字符串。