java – 为什么我可以访问另一个包的其他子类中的finalize()方法?

我是Java新手第一次尝试学习Java.
我的简单问题是java.lang.Object中的finalize()方法.为什么我在其他类中访问这个受保护的方法而不是其他受保护的方法.我的导师告诉我,protected只在其类,相同的包及其子类中有范围.Here我读过这个.

有人可以解释我是否有任何特殊情况与finalize()方法.我有一个答案不满意为什么finalize()受到保护here
我的守则如下:

//Creating Package Foo
package Foo;
class A
{
    protected finalize() 
    { 
        System.out.println("This is finalize method of Class A");
    }
}

// Creating Another Pacakage Foo1
package Foo1;
import Foo.*;
class B extends A
{
}
class C extends B
{
}
class D extends C
{
    public void foo() {
        C ob = new C();
        ob = null;
        System.gc(); // Why class A finalize() is getting call
    }
}

只有在finalize()的情况下才会被调用,而不是在另一种情况下.
问我的导师,他拒绝回答他说你做错了我会看,但他没有回复我.

请想想我对java的兴趣.也许我在犯一些大错.

解决方法:

这按预期工作,我不认为finalize()方法与Java中的任何其他方法的处理方式不同.可能被认为有点不同的是,finalize()方法通常仅由JVM垃圾收集器本身调用,如JavaDoc中所述:

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

另请注意,Josh Bloch在Effective Java强烈警告不要使用终结器:

Finalizers are unpredictable, often dangerous, and generally unnecessary. Their use can cause erratic behaviour, poor performance, and portability problems. Finalizers have a few valid uses … but as a rule of thumb you should avoid finalizers.

请考虑以下示例,它类似于您的示例:

具有覆盖finalize()方法的基类.

public abstract class BaseClass {
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("BaseClass finalisation occured");
    }
}

一个不覆盖finalize的子类:

public class SubClass extends BaseClass {
    public void foo() {
        System.out.println("SubClass Foo'd");
    }
}

还有一个驱动程序类,它具有运行所有内容的基本主方法:

public class Driver {
    public static void main(String[] args) {
        SubClass sc = new SubClass();
        sc.foo();
        sc = null;
        System.gc();        
    }
}

我们得到的输出如下:

SubClass Foo'd
BaseClass finalisation occured

Java方法查找(用非常简单的术语)发生的是在当前类中查找任何方法,如果没有,则在找到所需方法之前爬上类层次结构.在上面的示例中,当在SubClass对象上调用foo()方法时,SubClass类包含方法定义,以便使用实现,并且不会爬升类层次结构.当调用finalize()方法时(因为已经请求了System.gc()),首先在SubClass类中查找该方法,但是因为它不包含finalize()的实现,所以它的父类(BaseClass)被搜查. BaseClass确实包含finalize()的实现,因此使用它,并将一行打印到stdout.

现在考虑再次覆盖finalize()的子子类:

public class OverridenSubClass extends SubClass {
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("Overriden finalize called, which calls super's finalize first");
    }
}

并稍加修改的Driver类:

public class Driver {

    public static void main(String[] args) {
        OverridenSubClass sc = new OverridenSubClass();
        sc.foo();
        System.out.println(sc.toString());
        sc = null;
        System.gc();
        System.exit(0);
    }
}

其中产生以下输出:

SubClass Foo'd
finalize.OverridenSubClass@7150bd4d
BaseClass finalisation occured
Overriden finalize called, which calls initial finalize first

希望这是预期的.这里唯一需要注意的有趣事情是:

>我们不会在任何类中覆盖toString(),因此使用了Object.toString()实现.
>变量sc的类型不是决定所使用的方法实现的因素 – 它是sc引用的实际对象的类型

上一篇:聊聊Dotnet的垃圾回收


下一篇:【转载】终结方法使用及注意