我有点困惑,显然在这里遗漏了一些东西:
我读到java.lang.String的“是常量;它们的值在创建后无法更改。”
但如果我写下面的代码:
String line;
line = "Test1";
System.out.println(line);
line = "Test2";
System.out.println(line);
终端输出:
Test1
Test2
看来我可以设置一个值,然后再为字符串设置另一个值。
如果我这样尝试没有区别:
String line2 = "Test3";
System.out.println(line2);
line2 = "Test4";
System.out.println(line2);
我仍然可以在最初设置之后设置该值。
我在哪里错了?
感谢。
答案 0 :(得分:4)
字符串是不可变的,它们的值无法更改。那是真实的。
但是在您的代码中,您正在使用引用。
String line; //allocate variable
line = "Test1"; //assign to variable value "Test1"
System.out.println(line);
line = "Test2"; //assign to variable value "Test2"
你不能改变的是字符串本身而不是变量引用。
这适用于对象类型和原语。
答案 1 :(得分:3)
在JVM Test1和Test2中,在堆内存中创建了两个String值并分配了空间。你在做什么只是改变参考地址。这是代码语句的字节码。请关注ldc
操作码,因为您可以看到lcd
获得了不同的字符串引用。
public class JavaConstant extends java.lang.Object {
public JavaConstant();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String Test1
2: astore_1
3: getstatic #18 // Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_1
7: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/String
;)V
10: ldc #30 // String Test2
12: astore_1
13: getstatic #18 // Field java/lang/System.out:Ljava/io/PrintStream;
16: aload_1
17: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/String
;)V
20: return
}
答案 2 :(得分:2)
参见评论
String line; // declares a variable of type String
line = "Test1"; // creates a new String object with value "Test1" and makes line reference it
System.out.println(line); // don't care
line = "Test2"; // creates a new String object with value "Test2" and makes line reference it
这是两个不同的对象。
改变它的价值就是做这样的事情
line = "Test1";
line[4] = "2";
System.out.println(line); // printing Test2
这在Java中是不可能的,因为String
生成不可变实例。
分配引用和更改对象的值之间存在差异。
答案 3 :(得分:1)
字符串是不可变的。您无法更改String的值。 您可以创建一个新的String对象,也可以从String池中引用它。
String line; // line is at Location A
line = "Test1"; // Location A --> "Test1"
System.out.println(line); // Prints Test1
line = "Test2"; // Location A --> "Test2" --> Reference to Test1 is lost
System.out.println(line); // Prints Test2
答案 4 :(得分:1)
上面的所有答案都是正确的,String是不可变的,你不能编辑对象,另一方面你可以删除它们或编辑它们。
垃圾收集器将删除所有没有引用的对象,因为它们不能再使用了。
Java中有两个记忆:堆和堆栈。当变量存在于堆栈中时,对象存在于堆中。
创建时
String test1="Test1"
test1住在堆栈中,可以更改
然而,“Test1”生活不在Stack中,你无法编辑它。
String test1, test2;
test1 = test2 = "MyString"
如果更改test1 =“Hello”,test2将不受影响,也不会影响字符串本身。
Person person1, person2;
person1 = person2 = new Person("Nickname")
person1.rename("My new name");
另一方面,将编辑Person的名称(生活在堆中的对象)
它不需要更改Stack引用,person1和person2都会受到此更改的“影响”。