Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对象字段的终结_Java_Finalizer - Fatal编程技术网

Java 对象字段的终结

Java 对象字段的终结,java,finalizer,Java,Finalizer,我很难理解JavaSE8语言规范第12.6.1节和第12.6.2节的含义。我正在使用一种产品,其中Java对象管理本机对等点,因此正确完成(直到我们有机会重写ref队列)非常重要 从规范中可以明显看出,终结器可能会无序运行。这是可达性,我有一个困难的时间 我相信规范中说: class A { public Object o = new Object() protected synchronized void finalize() throws Throwable { o = nu

我很难理解JavaSE8语言规范第12.6.1节和第12.6.2节的含义。我正在使用一种产品,其中Java对象管理本机对等点,因此正确完成(直到我们有机会重写ref队列)非常重要

从规范中可以明显看出,终结器可能会无序运行。这是可达性,我有一个困难的时间

我相信规范中说:

class A {
    public Object o = new Object()
    protected synchronized void finalize() throws Throwable { o = null; }
}

class B {
    A a = new A()
    protected void finalize() throws Throwable {
        a.getClass()   // always works: a cannot be null.
        a.o.getClass() // might NPE: a's finalizer might have been run
    }
}

class C {
    A a = new A()
    protected void finalize() throws Throwable {
        synchronized (a) {
            a.getClass()   // always works: a cannot be null.
            a.o.getClass() // always works: a.o cannot be null.
        }
    }
}

上面有4个断言。我非常希望确认它们是真的,或者解释为什么一个或多个是假的。

如果
A.finalize
首先获得锁,那么
A.o.getClass()
即使在
C
中也会NPE。最后的断言是不正确的

关于可达性,可以这样想:假设
A
C
是循环可达的,那么在“同时”将达到不可达性。因此,
A
必须在
C
之前完成,这是不合理的


我想一个直接的解决办法可能是
a
的引用计数。然而,依靠GC清除非内存资源并不是一件好事。

正确地完成任务时要格外小心,因为完成任务基本上只能在对象未正确处理的情况下用作故障保护。正如您所注意到的,它周围的保证很少。大多数做您正在谈论的事情(例如SWT)的库都明确地要求使用
dispose
方法或类似方法,而Java try with resources使处理变得更简洁。对。愚蠢的例子。在a完成之前,C可能不会抓住a上的锁。菲。你相信其他3个断言是准确的吗?我不理解你关于可达性的讨论:问题是A可能在B或C之前完成。@G.BlakeMeike-Yup<代码>A可能在
B
C
之前完成,即使它们在引用
A
之前完成。即使
A
有一个字段
public,这也是正确的
C
有一个构造函数
C(){a.C=this;}
。是的。如果我理解正确的话,构造函数的问题似乎无关紧要。重要的是,无论最终确定的顺序如何,B和C都不会将字段“a”视为null。A的实例可能已经定稿,但引用从来都不是空的。我希望编辑可以直接回答这个问题。尽管如此,答案依然存在。。。如果隐藏在评论中。@G.BlakeMeike是的。我想是在最后一次使用和最终定稿之间。