finalize()为什么不能在main方法中使用
今天在看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()方法的权限修饰为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方法显然是不行的。可能文字生僻难懂,所以我们用一张图来面描述这样的关系
由于所有的类都是继承的Object类,所以他们本身是不具备finalize方法的,他们所调用的finalize方法是使用的他们的祖先类Object中的finalize方法。
由于finalize方法是protected的,只能被他的同一类、包或者子孙类使用,注意这里的他值指的是Object。
如果把A类和Test类看作一对兄弟,那么finalize方法就是他们父亲Object留给他们的受保护的遗产。A可以使用父亲留给他的遗产,Test可以使用父亲留给他的遗产,后面就是关键了,如果Test想要使用A类(A a = new A();)中没有公开的财产(变量和方法)尤其是受保护的遗产(a.finalize();)显然是不行的。