欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

finalize()为什么不能在main方法中使用

程序员文章站 2024-03-21 08:11:40
...

今天在看Thinking In Java的时候突然思考到了finalize()的问题。发现在main()方法中无法调用,从而引发了一连串的思考,在询问了公司架构师之后得到了解决。对static方法、protected关键字的使用有了更深的了解。


首先发现的问题是考虑到所有的类都是继承的Object类,那么不是应该都可以使用父类的方法嘛,事实上在main方法中并没有找到Object类中的任何方法。

后来注意到由于main方法是静态方法,静态方法中无法直接调用非静态方法,所以一定调用非静态方法,需实例化包含非静态方法的类的对象。

public class Test {



    public static void main(String[] args) {
        Test t = new Test();
        try {
            t.finalize();
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }



}

那么问题又出现了,当我在main方法中实例化Object之后为什么同样无法找到finalize方法呢??

通过查阅api我们发现
finalize()为什么不能在main方法中使用

finalize()方法的权限修饰为protected。
而我们所知的权限修饰作用于域

          public    protected     default        private
同一个类     √          √            √            √
同一个包     √          √            √
子类         √          √
不同包       √

而Object不属于和我们test类中同一包或类下的关系,所以无法使用object对象中的finalize()方法。

后来为了测试我又在同一包下创建了一个类A,尝试在main方法中实例化A并调用A的finalize()方法。出现了新的问题。

class A{


}

public class Test {

    public void a(){
        try {
            finalize();
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Test t = new Test();
        A a = new A();
        //a.finalize();//The method finalize() from the type Object is not visible
        try {
            t.finalize();
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }



}

后来仔细思考发现了问题,之所以Test类中的main方法可以直接实例化test对象后使用finalize()方法,是因为他是Object的子类,protected的方法是可以被子孙类调用的。而对象main方法中想要调用A对象的finalize方法显然是不行的。可能文字生僻难懂,所以我们用一张图来面描述这样的关系

finalize()为什么不能在main方法中使用

由于所有的类都是继承的Object类,所以他们本身是不具备finalize方法的,他们所调用的finalize方法是使用的他们的祖先类Object中的finalize方法。

由于finalize方法是protected的,只能被他的同一类、包或者子孙类使用,注意这里的他值指的是Object。
如果把A类和Test类看作一对兄弟,那么finalize方法就是他们父亲Object留给他们的受保护的遗产。A可以使用父亲留给他的遗产,Test可以使用父亲留给他的遗产,后面就是关键了,如果Test想要使用A类(A a = new A();)中没有公开的财产(变量和方法)尤其是受保护的遗产(a.finalize();)显然是不行的。