类和对象的初始化顺序(博客)
- 虚拟机在首次加载Java类时,会对静态代码块、静态成员变量、静态方法进行一次初始化(静态间按顺序执行)。加载后就一直存在于虚拟机中,所以仅初始化一次。
静态方法确实已经在类加载时初始化了,但是用不到。对于静态方法和非静态方法都是被动调用,即系统不会自动调用执行,所以用户没有调用时都不执行。
2. 只有在调用new方法时才会创建类的实例。
3. 类实例创建过程:先父类再子类。
父类的静态->子类的静态->父类的初始化块->父类的构造方法->子类的初始化块->子类的构造方法
4. 类实例 (对象)销毁时候:首先销毁子类部分,再销毁父类部分。
父类和子类都重写finalize方法,main()中主动调用。先调用子类的finalize方法,再是父类。但是finalize方法不一定会回收对象。
package exercise;
public class Main_exer {
void myMethod(Object o){
System.out.println("object");
}
void myMethod(String s){
System.out.println("string");
}
public static void main(String[] args) {
Main_exer ma = new Main_exer();
ma.myMethod(null);
}
}
第二个方法不被执行。执行最近的一个方法,子类方法。
main(){
Person pp = null;
}
会加载类,进行类的初始化。只执行static相关,static field和 static {}。
main(){Person p = new Person()}
不仅会类的初始化,构造函数执行后还会进行对象的初始化。初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。括号里的顺序,是代码的先后顺序决定的。
当所有【第一条出现类的语句中的所有类】必要的类都已经装载结束,开始执行main()方法体。
存在父类子类的情况
package learn;
class Father{
static String staticField = "父类的静态成员变量";
String field = "父类的成员变量";
static{
//System.out.println(staticField);
System.out.println("父类的静态初始化代码块");
}
static{
System.out.println(staticField);
//System.out.println("父类的静态初始化代码块");
}
{
System.out.println(field);
System.out.println("父类的普通初始化代码块");
}
public static void staticMethod(){
System.out.println("父类的静态方法");
}
public void method(){
System.out.println("父类的普通方法");
}
Father(){
System.out.println("父类的构造方法");
}
protected void finalize() throws Throwable
{
// TODO Auto-generated method stub
super.finalize();
System.out.println("销毁父类");
}
}
class T{
static String a = "其他类的静态变量";
String b = "其他类的普通变量";
static{
System.out.println(a);
System.out.println("其他类的静态初始化块");
}
{
System.out.println("其他类的普通初始化块");
System.out.println(b);
}
public void a(){
System.out.println("其他类的普通方法");
}
public T(){
System.out.println("其他类的构造方法");
}
}
public class Person extends Father{
static String tttstaticField = "子类的静态成员变量";
String field = "子类的成员变量";
static{
String tttstaticBlock = "子类的静态初始化代码块";
System.out.println(tttstaticBlock);
System.out.println(tttstaticField);
}
{
String tttblock = "子类的普通初始化代码块";
System.out.println(field);
System.out.println(tttblock);
}
public static void tttstaticMethod(){
System.out.println("子类的静态方法");
}
public void tttmethod(){
System.out.println("子类的普通方法");
}
Person(){
System.out.println("子类构造方法");
}
protected void finalize() throws Throwable
{
// TODO Auto-generated method stub
super.finalize();
System.out.println("销毁子类");
}
public static void main(String[] args) {
System.out.println("main方法");
//Person pp = null;
// Person p = new Person();//创建子类对象会先调用父类的构造方法,再调用子类的构造方法。
Father f = new Father();
Person child = new Person();
try {
child.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
T t = new T();//这种情况下 T类的装载时发生在上一个对象先初始化的前提下
t.a();
}
}
(父类的静态初始化代码块父类的静态成员变量)
(子类的静态初始化代码块子类的静态成员变量)
main方法
(父类的成员变量父类的普通初始化代码块)
父类的构造方法
(子类的成员变量子类的普通初始化代码块)
子类构造方法
(其他类的静态变量 其他类的静态初始化块)
(其他类的普通初始化块 其他类的普通变量)
其他类的构造方法
其他类的普通方法
除了静态的,其他都是可以反复执行的。