如果我有2个引用类型,具有相同的值,那么这意味着内存中只有1个对象

Dav*_*ave 4 java pointers

我是Java的新手,并且已经阅读了我认为的相互矛盾的陈述.请考虑以下代码.

String str1 = "dave";
String str2 = "dave";
Run Code Online (Sandbox Code Playgroud)

str1和str2虽然是唯一变量,但它们引用完全相同的值.那么,在内存中创建了多少个唯一对象?1或2,可以解释一下为什么?

ghd*_*lum 14

在你的榜样,他们引用同一个对象,因为字符串实习.

通常,使用new会创建新对象,因此使用:

String str1 = new String("dave");
String str2 = new String("dave");
Run Code Online (Sandbox Code Playgroud)

会在堆中创建两个不同的对象.


Rei*_*eus 9

您有一个唯一的Object&2个引用指向同一个对象.这是String汇集(或实习)的结果.鉴于两个String文字具有相同的内容,确保可以创建2个单独 的唯一方法Objects是显式调用其中一个String构造函数.

  • 你不能_change_` str1`(除非通过反射),因为`Strings`是不可变的.您可以将引用更改为指向不同的`String`.在这种情况下,其他参考的值不受影响. (8认同)
  • @cwhsu:确切地说!(虽然"make一个新的字符串对象"*可以替换为*"从正确的字符串池中取出正确的字符串对象",如果之前已经需要`"dave2"`). (2认同)
  • @cwhsu它只会创建一个匹配的新的`String`,它不存在于池中. (2认同)

Joa*_*uer 9

它并不复杂.除非你在谈论字符串;-)

首先,让我们忽略字符串并假设这个简单的类型:

public class ValueHolder {
  private final int value;

  public ValueHolder(int value) {
    this.value = value;
  }

  public int getValue() {
    return value;
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您有两条这样的行:

ValueHolder vh1 = new ValueHolder(1);
ValueHolder vh2 = new ValueHolder(1);
Run Code Online (Sandbox Code Playgroud)

那么你将在堆上创建正好2个对象.尽管它们的行为完全相同并且存储了完全相同的值(并且无法修改),但您将拥有两个对象.

所以vh1 == vh2会回来false!

String对象也是如此:可以存在两个String具有相同值的对象.

但是,有一个特定的事情String:如果在代码中使用String文字(*),Java将尝试重新使用任何更早出现的内容(通过一个名为interning的过程).

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

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