如果我有两个引用类型,具有相同的值,这是否意味着内存中只有一个对象



我是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将尝试重用此先前出现的任何内容(通过称为实习的过程)。

所以在你的示例代码中,str1str2 将指向同一个对象

(*),或者更准确地说:类型为String的编译时常量表达式。

你有一个独特的Object &两个引用指向同一个对象。这是String池化(或实习)的结果。如果两个String字量具有相同的内容,那么确保创建两个分隔的 Objects的唯一方法就是显式地调用String的一个构造函数。

看情况。如果您编写了一个小测试程序,那么它们很有可能包含相同的引用,因为Java试图通过节省内存和重用引用来帮助您。如果str2来自用户输入,那么它可能是两个不同的引用。一个好的测试方法是在比较中使用==。如果两者是==,则它们引用相同的内存位置。如果不是,那么它们就是两个不同的引用。这让许多初级程序员感到困惑,因为当他们第一次开始编写代码时,他们使用==,看到它可以工作,然后就无法弄清楚为什么他们的比较不起作用。

我不能具体解释什么时候Java在"幕后"重用引用,但它与如何以及何时创建值有关

你正在写这篇文章的简写版

String str1 = new String("dave");
String str2 = new String("dave");

所以str1和str2是不同的对象,可以单独修改

"dave",原始字符串,只在内存中存在一次,与另一个引用。

最新更新