我是Java新手,读过与我所相信的相矛盾的陈述。请考虑以下代码:
String str1 = "dave";
String str2 = "dave";
str1和str2虽然是唯一的变量,但它们引用的是完全相同的值。那么,在内存中创建了多少唯一对象?1或2,有人能解释为什么吗?
在您的示例中,它们引用相同的对象,因为字符串是内部的。
通常,使用new创建新对象,因此使用:String str1 = new String("dave");
String str2 = new String("dave");
将在堆中创建两个不同的对象。
其实没那么复杂。除非你讨论的是字符串;-)
首先,让我们忽略string并假设这个简单的类型:
public class ValueHolder {
private final int value;
public ValueHolder(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
如果你有这样的两行:
ValueHolder vh1 = new ValueHolder(1);
ValueHolder vh2 = new ValueHolder(1);
则在堆上恰好创建了2个对象。即使它们的行为完全相同,并且存储了完全相同的值(并且不能修改),您将拥有两个对象。
所以vh1 == vh2
将返回false
!
对于String
对象也是如此:两个具有相同值的String
对象可以存在。
然而,关于String
有一件特别的事情:如果你在代码中使用String
文字(*), Java将尝试重用此先前出现的任何内容(通过称为实习的过程)。
str1
和str2
将指向同一个对象。
(*),或者更准确地说:类型为String
的编译时常量表达式。
你有一个独特的Object
&两个引用指向同一个对象。这是String
池化(或实习)的结果。如果两个String
字量具有相同的内容,那么确保创建两个分隔的 Objects
的唯一方法就是显式地调用String
的一个构造函数。
看情况。如果您编写了一个小测试程序,那么它们很有可能包含相同的引用,因为Java试图通过节省内存和重用引用来帮助您。如果str2来自用户输入,那么它可能是两个不同的引用。一个好的测试方法是在比较中使用==。如果两者是==,则它们引用相同的内存位置。如果不是,那么它们就是两个不同的引用。这让许多初级程序员感到困惑,因为当他们第一次开始编写代码时,他们使用==,看到它可以工作,然后就无法弄清楚为什么他们的比较不起作用。
我不能具体解释什么时候Java在"幕后"重用引用,但它与如何以及何时创建值有关
你正在写这篇文章的简写版
String str1 = new String("dave");
String str2 = new String("dave");
所以str1和str2是不同的对象,可以单独修改
"dave",原始字符串,只在内存中存在一次,与另一个引用。