java中的字符串引用类型与其他对象的比较

k5ifujac  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(333)

这个问题在这里已经有答案了

java对象分配(8个答案)
27天前关门了。
所以我看了一个介绍性的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!

作为输出。
为什么会发生这种情况,这是否意味着字符串是一种特殊类型的引用类型,因为它们通常用于?

wooyq4lh

wooyq4lh1#

我在python中处理很多事情,情况也是如此。以存储了多个值的列表为例。当您用python编写了相当于您的代码时,这种情况就会改变。字符串不会像你说的那样改变。代码的问题是对象和类(如列表)会发生变化,因为它们没有存储在内存中。它们只是引用,而不是新对象。当您重新分配一个字符串时,分配工作正常,因为它只是一个值。

x7rlezfr

x7rlezfr2#

string在java中是一个“特殊”对象。它是一个不可变的对象(固定的,不能修改),并且是唯一可以在没有new关键字的情况下声明的对象。
如果您使用stringbuilder,stringbuffer这些是可变的字符串,您的值将在更改时被修改。
深入研究java字符串时,会有许多令人困惑的理解。当您使用“==”时,两个具有相同值的不同字符串返回相同的内存地址引用。如。

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指向新对象,s2指向旧对象。
当你回顾你的例子时

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”、“method”之类的内容,以便保留被修改的相同对象。因此类似于:

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.
ykejflvf

ykejflvf3#

java中的字符串是不可变的对象。他们从不改变。当你做一个新的赋值时,它只是创建一个新的字符串。旧的仍由垃圾收集器收集。point类不是不可变的对象。

相关问题