我有时会假设如果oldObject != newObject
那么对象已经改变了 - 在大多数情况下这似乎是一个公平的假设,但这是否真的是一个错误的假设?
简而言之,在什么情况下,以下代码可以打印“相同!”?
static WeakReference<Object> oldO = null;
...
Object o = new Object();
oldO = new WeakReference(o);
// Do some stuff with o - could take hours or even days to complete.
...
// Discard o (or let it go out of scope).
o = null;
// More stuff - could be hours or days later.
...
o = new Object();
// Later still.
if ( o == oldO.get() ) {
System.out.println("Same!");
}
我意识到这确实是远程可能的,因为对象引用本质上是对象的内存地址(或者可能在某些JVM中)。但它有多大可能?我们是否在实际发生之前谈论了几十年的运行时间?
加
我的道歉 - 请假设oldO
是weak
某种形式的Weak
引用,并不能阻止它被收集。也许它是{{1}},因为代码(现在)建议或者引用存储在数据库或某个文件中。
答案 0 :(得分:4)
永远不会是一样的。 oldO将始终引用初始对象,因此永远不会丢弃它,并且新对象不能具有相同的地址。
更新:似乎更新了答案以指定oldO
是弱引用。在这种情况下,当对象消失时,oldO
的引用将变为null。这意味着它永远不会匹配JVM中的另一个对象。
答案 1 :(得分:4)
(我正在回答我认为你真正想知道的事情,而不是你所拥有的特定片段)
它依赖于实现。对象引用的契约是,只要对象仍然存在,没有其他对象将==与它进行比较。这意味着在对象被垃圾收集之后,VM可以自由地重用相同的对象引用。
Java的实现可以选择使用递增的整数进行对象引用,在这种情况下,当引用计数器溢出回0时,只能获得相同的对象引用。其他实现可能使用内存位置,这使得它更有可能相同的参考资料可以重复使用。在任何情况下,如果重要,您应该定义自己的对象标识。
答案 2 :(得分:3)
他们不可能平等。您仍然可以引用旧对象(oldO
),因此永远不会丢弃它。
答案 3 :(得分:1)
o == oldO
表示o
与oldO
的内存地址相同。所以,除非在某个时候你做o = oldO
或oldO = o
,否则这种情况不可能发生。通过传递性,当然,做foo = o; oldO = foo
或任何等价物会达到相同的效果。
答案 4 :(得分:1)
首先,内存地址无关紧要。 Java不是C.对象标识是一种JVM实现 - 它可能依赖或者不依赖于内存地址,但更可能不依赖于内存地址,因为JVM可以自由地在内存中移动对象但必须保持其身份。 / p>
但无论如何。因为你持有对原始对象的引用,所以第二个不能是“相同”的对象。
答案 5 :(得分:0)
永远不会发生。
您的第一个对象(oldO
)存储在特定的内存位置。
只要引用oldO,您的第二个对象将系统地在另一个memery位置被引用。
所以oldO == o
将比较两个内存地址,这些地址总是不同的。
如果你取消引用oldO,它将被垃圾收集,你将能够在同一地址创建一个新对象。但是你无法将它与oldO进行比较,因为它已被解除引用。
答案 6 :(得分:0)
通过引用旧对象,可以防止它被垃圾收集,因此可以防止新对象可以使用这些内存,因此它们永远不会相等。
我想知道你是否使用了SoftReference,你可以保留对旧对象的引用,同时允许它被垃圾收集但是:
1)一旦收集旧对象,我假设,SoftReference设置为null并且
2)这是人为地试图强迫这种情况,因此并没有真正证明什么: - )
答案 7 :(得分:0)
According to the documentation,当对象被垃圾收集时,将清除弱引用。它没有指定“清除”意味着什么,但可能是设置为null。如果它实际上设置为null,则永远不会将null = =声明为任何对象引用,无论其内存位置如何。