Java 中的字符串引用类型与对象方面的其他类型

String Reference type in Java versus others in terms of objects

所以我在看一个介绍性的 Java 教程,它说如果你声明一个引用类型,另一个等于那个对象,如果你改变第一个对象,第二个对象将改变为出色地。例如:

Point p1 = new Point(1, 1);
Point p2 = p1;
p1.x = 5;
System.out.println(p2);

这会给我一个输出

java.awt.Point[x=5,y=1]

但是,我用字符串尝试了这个:

String s1 = "Hello, World!";
String s2 = s1;
s1 = "Goodbye, World!";
System.out.println(s2);

但我得到了

Hello, World!

作为输出。

为什么会出现这种情况,这是否意味着字符串是一种特殊类型的引用类型,因为它们通常被使用?

Java 中的字符串是不可变对象。他们永远不会改变。当你做一个新的赋值时,它只是创建一个新的字符串。旧的仍然由垃圾收集器收集。您的观点 class 不是不可变对象。

字符串是 java 中的一个 'special' 对象。它是一个不可变对象(固定且无法修改),并且是唯一可以在没有 new 关键字的情况下声明的对象。

如果您使用 StringBuilderStringBuffer,这些是可变字符串,您的值将在更改时修改。

当你深入研究时,Java String 有许多令人困惑的理解。当您使用“==”时,2 个具有相同值的不同字符串 returns 内存地址的相同引用。例如

String a1 = "abc"
String a2 = "abc"
a1 == a2 //returns true because a1 and a2 points to same reference (but not always!)
a1 == new String("abc") //returns false
/**Do use "equals", not == for string's value comparison**/

如果您可以将注意力集中在内存对象引用上:

String s1 = "Hello, World!"; //let's say it's allocated to memory address 0x0012
String s2 = s1; //s2 points to same memory address 0x0012
s1 = "Goodbye, World!"; //s1 points to new memory address 0x1113
System.out.println(s2) //printing value in still in memory address 0x0012

相当于,s1指向新的Object,s2指向旧的Object。

当你回顾你的点示例时

Point p1 = new Point(1, 1);
Point p2 = p1; //p2 is referring to p1's memory address
p1.x = 5;  
p1 = new Point(2,2); //Assign to new memory address, here is like the line for s1="Goodbye,world"
System.out.println(p2.x); //You now still get 5, because it's still old object.

因此,要修复一个可变的字符串,您需要更改诸如“Class”、“方法”之类的内容,以便保留被修改的同一对象。因此是这样的:

StringBuilder sb1 = new StringBuilder("Hello World");
StringBuilder sb2 = sb1;  //Points to same reference address.
sb1.append("Goodbye World");
System.out.println(sb2.toString()); //Now you get Hello WorldGoodbye World.
sb1.setLength(0).append("Goodbye World"); //clear then set to new value.
System.out.println(sb2.toString()); //Now you get Goodbye World.

我在 python 处理过很多事情,情况也一样。以一个列表为例,它存储了多个值。当您完成 python 中的等效代码时,情况将会改变。字符串不会像你所说的那样改变。代码的问题是对象和 类 之类的列表会发生变化,因为它们没有存储在内存中。它们只是引用,而不是新对象。当您重新分配一个字符串时,分配工作正常,因为它只是一个值。