Java学习笔记汇总
待学习
...
Java多态的实现机制是什么
- 子类继承父类并覆写了父类的方法,当以父类声明并初始化一个子类型的时候,在运行的时候,是怎么找到子类,并调用子类的方法的。答案:方法表。
参考链接:
Java类初始化顺序
对于一个类而言,按照如下顺序执行:
-
执行静态代码块
-
执行构造代码块
-
执行构造函数
-
对于静态变量、静态初始化块、变量、初始化块、构造函数,它们的初始化顺序依次是(静态变量、静态初始化块)->(变量、初始化块)->构造函数。
当涉及到继承时,按照如下顺序执行:
- 执行父类的静态代码块,并初始化父类静态成员变量
- 执行子类的静态代码块,并初始化子类静态成员变量
- 执行父类的构造代码块,执行父类的构造函数,并初始化父类普通成员变量
- 执行子类的构造代码块, 执行子类的构造函数,并初始化子类普通成员变量
参考链接:
Java对象的finalize方法
protected void finalize() throws Throwable { }
-
当 GC (垃圾回收器) 确定不存在对该对象的引用时,对象的垃圾回收器就会调用这个方法。子类可以覆盖finalize方法来处理系统资源或者执行清理操作。
-
finalize的一般约定是,当JVM已经确定,任何尚未终止的线程都无法再通过任何方式访问该对象(除非是由于其他已准备好终结的对象或类的终结操作产生的结果),那么就会调用该对象的finalize方法。注意: "除非是由于其他已准备好终结的对象或类的终结操作产生的结果",这一段我的理解就是其他对象在finalize方法中引用了该对象。
-
finalize方法内部可以执行任何操作,包括让该对象重新在其他线程可用;但是,finalize的通常作用是在对象不再需要的时候执行清理操作。例如,关闭输入输出流等等。
-
Java语言不保证哪个线程会调用指定对象的finalize方法。但是,Java语言保证,调用finalize方法不会持有任何用户可见的同步锁。当在finalize方法中抛出一个一个未捕获的异常时,异常会被忽略,该对象的
finalization
会终止。 -
在一个对象的finalize方法被调用后,不会有任何其他操作,直到JVM重新确定任何尚未终止的线程都无法再通过任何方式访问该对象(包括其他已准备好终结的对象或类),那么此时,该对象会被永久抛弃(回收)。
-
任何一个对象的finalize方法只会被JVM调用一次。
-
finalize中抛出的未捕获的异常会导致该对象的
finalization
终止,但是异常会被忽略。 -
当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。(这个没有验证。)
举个例子
public class TestFinalizeMethod extends GregorianCalendar {
public static void main(String[] args) {
Cake c1 = new Cake(1);
Cake c2 = new Cake(2);
Cake c3 = new Cake(3);
Person person = new Person(c2);
c2 = c3 = null;
person = null;
System.gc(); //调用Java垃圾收集器
}
static class Cake {
private int id;
public Cake(int id) {
this.id = id;
System.out.println(this.toString() + " id = " + id + " is created");
}
public void test() {
System.out.println(this + " id = " + id + " test");
}
protected void finalize() throws java.lang.Throwable {
super.finalize(); //finalize的调用方法
System.out.println(this.toString() + " id = " + id + " is disposed");
}
}
static class Person {
Cake cake;
public Person(Cake cake) {
this.cake = cake;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println(this + " finalize");
cake.test();
}
}
}
输出结果
com.hm.base.TestFinalizeMethod$Cake@27c170f0 id = 1 is created
com.hm.base.TestFinalizeMethod$Cake@5451c3a8 id = 2 is created
com.hm.base.TestFinalizeMethod$Cake@2626b418 id = 3 is created
com.hm.base.TestFinalizeMethod$Person@71369540 finalize
com.hm.base.TestFinalizeMethod$Cake@5451c3a8 id = 2 test
com.hm.base.TestFinalizeMethod$Cake@2626b418 id = 3 is disposed
com.hm.base.TestFinalizeMethod$Cake@5451c3a8 id = 2 is disposed