Java 参考变量数组
我的文本要求我计算对一个对象的引用。给定代码中包含以下内容:Java 参考变量数组,java,arrays,garbage-collection,Java,Arrays,Garbage Collection,我的文本要求我计算对一个对象的引用。给定代码中包含以下内容: Honey honeypot = new Honey(); Honey [ ] ha = {honeypot, honeypot, honeypot, honeypot}; Bees b1 = new Bees(); b1.beeHA = ha; 其中Bees的构造函数创建Honey[]beeHA数组 现在我认为,beeHA将像arrayha一样将引用honeypot保存在四个位置,并且这将是四个单独的引用,加上来自ha数组的
Honey honeypot = new Honey();
Honey [ ] ha = {honeypot, honeypot, honeypot, honeypot};
Bees b1 = new Bees();
b1.beeHA = ha;
其中Bees
的构造函数创建Honey[]beeHA
数组
现在我认为,beeHA
将像arrayha
一样将引用honeypot
保存在四个位置,并且这将是四个单独的引用,加上来自ha
数组的四个引用,形成八个引用。但是书中给出的回答是,beeHA
数组只指向ha
数组,而不是指向honeypot
引用变量所引用的对象,该引用变量只进行了四次引用。我想得对吗
如果数组
ha
被垃圾收集(本章主题),那么它就不会b1。beeHA[x]
仍然包含蜜罐引用变量?Java类型系统中的关键区别在于值语义和引用语义:当你说x=y代码>,然后复制值,并对引用使用别名
基本类型(如int
)具有值语义;类类型和数组具有引用语义。所以当你说b1.beeHA=ha
,您将引用别名为数组,也就是说现在ha
和b1.beeHA
都引用相同的数组
垃圾收集器在仍然存在对数组的引用时不会收集该数组。ha
不是数组,而是一个变量。变量的值是对数组的引用,就像b1.beeHA
的值一样。所以说“arrayha
”被垃圾收集是没有意义的。当你写作时:
b1.beeHA = ha;
只需将ha
的值复制到b1.beeHA
。它不是复制数组,而是复制引用
您所展示的代码创建了一个数组,其中包含对Honey
的一个实例的四个引用。该数组有两个引用-一个在变量ha
中,另一个在变量b1中。beeHA
没有更多上下文,您的示例有点混乱;我看不到这些变量的作用域
如果有一个对象持有对该对象的引用,则该对象不会被垃圾收集。蜜罐引用指向蜂蜜的新实例;ha阵列也是如此。b1实例指向ha阵列
如果绘制对象图,b1实例将指向ha,后者将指向蜜罐
如果b1是垃圾收集的,那么整个图是合格的
只要b1和ha存在,蜂蜜实例就不会被GC处理。事实上,我认为即使这样,它也会变得比需要的更复杂。赋值总是将RHS的值复制到LHS。只是如果x
和y
属于类类型,那么变量的值就是一个引用-仅此而已。没有别名,因为x
和y
变量没有绑定在一起-它们只是碰巧有相同的值,这是一个引用。@JonSkeet:我想你描述的是实现者的视角。从语言的角度来看,没有“引用类型”,因此如果这有意义的话,您的语句不能真正用语言本身来表达。(例如,Java类型系统指定的蜜罐
的类型实际上是蜜罐
,而不是一些神秘的“可分配引用到蜜罐
”)如果语言中没有“引用类型”,为什么JLS第4.3节的标题是“引用类型和值”?第4.3.1节:“一个对象是一个类实例或数组。引用值(通常只是引用)是指向这些对象的指针,以及一个特殊的空引用,它不指向任何对象。”这里没有什么神秘之处——都在规范中。它非常清楚地区分了引用和对象。我在规范中找不到“别名”一词的用法…(同样,从第4.1节开始:“Java编程语言中有两种类型:基本类型(§4.2)和引用类型(§4.3)。@JonSkeet:Fair。我想我的意思是类型系统没有不同的类型Honey
和“reference toHoney
”。代码表明,honeypot
是一个类型为Honey
的变量,因此我发现在值与引用语义方面的推理更为系统;当然,你是对的,JLS确实描述了引用类型。这对我来说是最有意义的。我想我认为有两个独立的数组对象,而不仅仅是一个有两个引用的数组对象。谢谢大家!