Java对象、引用变量和垃圾收集堆

Java对象、引用变量和垃圾收集堆,java,Java,我知道您可以创建2个对象引用变量,例如: Book b; Book c; 然后创建2个对象并使引用变量指向它们: b = new Book(); c = new Book(); 现在垃圾收集堆中还有2个对象 如果将b参考变量分配给c,即: c = b; GCH中的1个对象现在有资格进行垃圾收集,因此实际上有1个对象 但是如果您更改了b的某些内容,例如: b.setAuthor("New Writer"); 这是否意味着如果使用参考变量c: c.getAuthor(); 它会得到“ne

我知道您可以创建2个对象引用变量,例如:

Book b;
Book c;
然后创建2个对象并使引用变量指向它们:

b = new Book();
c = new Book();
现在垃圾收集堆中还有2个对象

如果将
b
参考变量分配给
c
,即:

c = b;
GCH中的1个对象现在有资格进行垃圾收集,因此实际上有1个对象


但是如果您更改了
b
的某些内容,例如:

b.setAuthor("New Writer");
这是否意味着如果使用参考变量
c

c.getAuthor();
它会得到“newwriter”,因为b和c都指向同一个对象

这看起来很奇怪,因为直觉上我认为如果你做了
x=y
,那么
y
应该仍然与
x
不同,当你在作业后改变事情时

这是否意味着如果你使用 参考变量c本身:

c、 getAuthor()

它会成为“新作家”,因为两者 b和c指向同一个对象

是的,至少对任何对象都是如此(与之相反)。最简单的方法可能是编写一个示例程序,看看它是如何工作的


(int、float、boolean等)可以很好地工作,就像您在
x=y
示例中描述的那样。

由于c现在是b的参考副本,对b的任何更改都将应用于c(除非它们是原语,在这种情况下传递的是值而不是地址)

这里有一个迂回的描述


要展开其他响应,请将“c=b”简单地看作是为“b”已经引用的对象创建别名或替代名称。实际上,这就是每次声明或赋值变量时要做的事情。“new Book()”在内存中创建了一些对象,但是“Book b=”在您的程序中为它命名,允许您访问它。

这是整个参考点变量
b.SetAuthor(…)
实际上是
[无论b指向什么].SetAuthor(…)
,在这种情况下
b
指向的内容与
c
指向的内容相同。“真实”对象在其他地方,而
b
c
都只是到达它的途径。在具有显式指针的语言中,这一点更为明显。

将b和c视为指向不同图书对象的框。现在,当
c=b
完成时,c框现在指向b所指向的任何对象。所以b和c都引用了完全相同的对象。更准确地说,当
c=b
完成时,c现在是b的别名。赋值意味着c得到b的值。对象在Java中存储为引用,因此c将只获取存储在b中的引用,该引用将引用b正在引用的图书对象


希望这能有所帮助。

处理Java时要记住的规则:

  • 变量不是对象。变量包含对象(或
    null
    )--特定对象可以同时存储在零个或多个变量中。这不会创建新对象,请参见#3

  • 改变对象会改变该对象。

  • 分配(或传递)对象不会进行复制/克隆/复制。

  • 虽然与“原语值”和实现细节存在差异,但根据上述规则,原语值可以被视为对象:所有原语值都是不可变的,如果它们被想象为单例(例如,只有一个0),那么等式(
    =
    )就是标识等式(因此副本是不可区分的). 我尽量避免使用“引用”一词:对象本身就是对象

    希望这些规则和注释能回答您的问题:-)


    愉快的编码。

    我喜欢它的发展方向(+1),但这是误导。它创建了一个别名——但不是b——“别名”是指在赋值(
    c=b
    )中求值时位于
    b
    中的对象。因此,变量
    c
    b
    在赋值后是同一对象的“别名”(但它们之间没有任何别名)。为了便于讨论,如果原语值被视为单例(例如,只有一个0)然后,基元类型和引用类型对
    ==
    运算符的作用没有区别;-)