【问题标题】:For the code given what will be stored in ArrayList? What are shallow pointers in Java?对于给出的代码,ArrayList 中将存储什么? Java中的浅指针是什么?
【发布时间】:2022-01-17 13:14:40
【问题描述】:

假设我们有三个 Bear 对象:mamma、poppa 和 baby。我们创建一个“熊”ArrayList 并将指向三个熊的指针添加到 ArrayList。

// Create three bears 
Bear momma = new Bear();
Bear poppa = new Bear(); 
Bear baby = new Bear(); 
 
// Create an ArrayList, add the three Bear pointers 
ArrayList bears = new ArrayList();
bears.add(momma); 
bears.add(poppa);
bears.add(baby);

上面的代码产生了文档中显示的内存结构。

请注意,bears.add(momma) 行不会将 momma Bear 对象的副本添加到 ArrayList。相反,它只是将指向 momma Bear 对象的指针添加到 ArrayList。在 Java 中,通常会有这样的“浅”指针指向一个对象——有一个对象有很多指向它的指针。

关于内存结构,请参考下面给出的文档第 3 页的图表: Document

我的疑惑,

1)有人能解释一下上面这段话想说什么吗?

  1. 文档中所说的java中的浅指针是什么意思?

  2. ArrayList 中究竟存储了什么。在显示结构的图像中,显示有两个指针指向 ArrayList 中的每个元素。

据我所知,ArrayLists 只能存储对象的引用变量。但是,从 ArrayList 中的块内部指向的指针是什么。

ArrayLists 中存储的是什么?

【问题讨论】:

  • 它存储对这些对象的引用。 “指针”不是您通常在 Java 中使用的术语。另请参阅"Is Java pass-by-reference or pass-by-value"
  • “指针”、“参考”... potayto potahto。大致意思相同,只是在java中我们称之为'参考'。
  • 我怀疑为什么我们有两个指针指向一个对象。例如 poppa po-+int 指向对象,而索引位置 1 处的指针指向同一个对象。

标签: java pointers arraylist


【解决方案1】:

Bear momma = new Bear();

这个代码是这个的简写:

Bear momma; [1]
new Bear(); [2]
momma = that thing; [3]

第一行创建了一个新变量,并将其命名为 momma。在 java 中,all 变量很小。想想带有标题的便利贴。所以,这会抓取一个便利贴,在上面写一个标题,然后将其留空。

第二行是一整只熊,它比便利贴大得多。请记住:如果您想要一只新熊,new Bear() 需要由您或其他人的代码执行。

第三行只是在你的便利贴上写下熊居住的地址

便利贴很小;他们有足够的空间容纳一个基元(intlongbytedoublefloatshortbooleancharacter - 这就是所有的基元,用语言硬编码) .. 或地址。

每当您调用一个方法时,您都会为您的 postit 制作一个副本(postit 很小,而且您有很多)并将副本交给该方法。该方法完成后,会将这些帖子扔进垃圾箱。

让我们尝试一些东西。假设熊有一个setName 方法。

Bear bear1 = new Bear();
Bear bear2 = bear1;
bear1.setName("Bruno");
System.out.println(bear2.getName());

这将打印布鲁诺! - 我们有 2 个 postits,两个都有相同的地址。只有一只熊。


Bear bear = new Bear();
bear.setName("Bruno");
test(bear);
System.out.println(bear.getName());

public void test(Bear bear) {
  bear.setName("Brenda");
}

这将打印“Brenda”。我们制作了一只新熊,然后我们有一张贴有这只熊地址的便利贴。然后我们复制这个 postit,把它交给测试方法。然后该方法会跟随它发布的地址(. 是 java 的:Follow (“取消引用”是官方术语)并告诉熊它在那里找到了它的名字。


private static final Bear brenda = new Bear("brenda");

...

Bear bear = new Bear();
bear1.setName("Bruno");
test(bear);
System.out.println(bear1.getName());

public void test(Bear bear) {
  bear = brenda;
}

这会打印布鲁诺!你可能已经预料到了布伦达。请记住,Java 中的= 是:“清除您的 postit 并复制此 postit 的地址”。

主代码将 postit 的副本传递给测试方法。然后这个测试方法会擦掉这个postit,在上面写下另一只熊的地址,然后把它扔进垃圾桶。 test 方法在这里没有用处。


ArrayLists 是 postits 的列表。不是熊的名单——这需要整个动物园,太笨重了。

Bear bear = new Bear();
List<Bear> bears = new ArrayList<Bear>();
bears.add(bear);
test(bears);
System.out.println(bears.get(0));

public void test(List<Bear> bears) {
  bears.clear();
  bears.add(brenda);
}

上面代码的测试方法从列表中删除了带有第一只熊地址的postit,然后添加了一个带有brenda地址的新postit。然后主代码从列表中获取第一个 postit 的副本。其中将有布伦达的地址。 (为什么要复制?一切都是复制品,一直都是。Java 正在复制数百万个帖子。从 CPU 的角度来看,它只是复制一个数字)。


Bear bear = new Bear("bruno");
bear = new Bear("brenda");

这是一只新熊,在你的便利贴上写下它的地址。

然后它又制造了一只熊(我们现在有 2 只熊)。然后它把地址划出给布鲁诺,然后把给布伦达的地址写在上面。

布鲁诺怎么了?布鲁诺在树林里迷路了。现在世界上有零个贴有布鲁诺地址的便利贴,所以这个信息(布鲁诺住在哪里)丢失了。布鲁诺还在,但我们不知道在哪里。森林辽阔,没关系,我们永远不会碰到他。

最终,垃圾收集器将完全摆脱 bruno。可怜的布鲁诺。

【讨论】:

  • System.out.println(bear1.getName());这将如何打印布伦达?它不应该打印 Bruno,因为 Bear1 指向一个名为 Bruno 的对象。如果我的解释有误,请纠正我。
  • 因为你把带有地址的邮递给布鲁诺,复制了那份邮递,然后交给test 方法。测试方法用它的 postit 走到那里告诉 bruno:嘿,你的名字现在是 brenda! - 然后那个方法就完成了。然后你拿着你的postit走到那里问:你叫什么名字? - 那只熊现在说:布伦达。
  • System.out.println(bear.getName());这不是 System.out.println(bear1.getName());前?您是否对代码进行了更改?
  • 那个 sn-p 以前不会编译,是的,我修好了。
  • 这样可以吗?我们可以说图中的第二个指针(箭头)或“位置”是 ArrayList 中节点(块)的内存地址(内存位置),因为每个块都会有自己的内存地址(内存位置)分配在一种连续的时尚?如果我错了,请纠正我。
猜你喜欢
  • 2010-09-06
  • 2020-09-01
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-07
相关资源
最近更新 更多