-2

Java 语言规范的第 4.3.1 节指出,“可能有许多对同一对象的引用。”。

但它也指出“引用值(通常只是引用)是指向这些对象的指针,以及一个特殊的空引用,它不引用任何对象。

所以,我的理解是“可能有很多指向同一个对象的指针。”但是我们怎么会有很多指针,这意味着不同的地址,都指向同一个对象呢?某个对象可以有不同的地址吗?

4

2 回答 2

1
Obj newObj = new Obj();

这会从“Obj”类在内存中创建一个新对象。

Obj newObj = new Obj();
Obj a1 = newObj;
Obj a2 = newObj;
Obj a3 = newObj;

a1,a2 和 a3 都引用同一个对象,意思是,它们都指向同一个对象。例如,如果您更改了 a2 中的值

System.out.println(a3.name) //prints carl
a2.name = "bob"
System.out.println(a3.name) //prints bob

它改变了 a2 指向的内存中对象的值。在本例中,该对象是 newObj。

这是一个你可以玩的小例子:

  class Main{
  public static void main(String[] args) {
    Book b = new Book("ey");
    Book b1 = b;
    Book b2 = b;
    System.out.println(b1.title); //ey
    System.out.println(b2.title); //ey
    System.out.println(b.title); //ey
    b2.title = "ok";
    System.out.println(b1.title); //ok
    System.out.println(b2.title); //ok
    System.out.println(b.title); //ok
  }
}

 class Book {
  public String title;
  public Book(String t){
    title = t;
  }
}

这是否清理了一些东西?

于 2021-12-01T10:51:15.023 回答
1

它只是意味着“许多变量都可以引用同一事物”。

List<String> list1 = new ArrayList<String>();
List<String> list2 = list1;

list1.add("Hello");
System.out.println(list2);

即使我们从未调用过,上面的代码也会打印 'Hello' list2.add。那是因为list1变量和list2变量都引用同一个对象,因此,如果您在取消引用时向您到达的对象添加一些内容,那么如果您取消引用( println 代码最终会这样做)list1,它也是可见的。list2

Java 中非原始类型的变量(无论是字段、局部变量还是参数)就像埋在沙子里的宝藏地图。.操作员(以及[]和其他一些) “synchronized (x)取消引用” - 正如它们在 java 术语中的意思:按照地图并挖掘。

第 4.3.1 节试图说:对于任何给定的宝藏,可能有许多地图都通向它。

不要将引用视为具有指示它在内存中的位置的数值。那是 C 的东西(是的,Java 有点像在引擎盖下工作,但这就是重点:它在引擎盖下;不可能看到这个数字,与之交互,对其进行算术等等。事实上,在大多数 JVM 上,那个“数字”不是内存地址,也不是直接的)。

您似乎将其解释为:对于任何特定对象,许多不同的“内存地址”都可以引用它。这不是它的意思。它只是意味着:多个变量可以保持相同的值。

这很简单:

int x = 5;
int y = 5;

也许你有点困惑,因为这看起来非常明显,但这就是第 4.3.1 节所要说明的内容。

于 2021-12-01T10:54:51.237 回答