实践时最好的学习方法。

类加载(下面会用到)的定义:当JVM第一次使用一个类时候,需要通过classpath找到.class字节码文件,读入这个类中的信息(包名,类型,属性,方法,静态变量,静态方法),并且保存在虚拟机中,而且类加载只进行一次。

类加载的时机:

1,创建对象时;2,通过(类名.静态成员名)访问静态成员时;3,子类进行类加载时(包括前面1和2两种情况)

 

现在总结有父类时对象的创建过程总体:

第1步:被static修饰的成员方法、属性和代码块之后就变成了静态成员方法、静态属性和静态代码块,和static修饰符有关的都是和对象无关的,所以在创建对象的时候会先执行父类类加载执行静态代码块,然后才进行子类的类加载执行子类的静态代码块。

第2步:a 为父类属性赋默认值;     b 父类(动态)代码块和成员属性的位置等同,没有先后只会按照从上到下的顺序执行 c 调用父类的构造方法

 

第3步:子类再执行重复父类abc操作 

 

 

 

第一步:进行了类加载

类加载的定义:

 

day12;//对象创建过程
/* 

结果我粘贴在最上面。

Super的静态代码块执行第1次
Sub的静态代码块执行第1次
为Super属性赋默认值
Super的动态代码块执行第1次
Super的无参构造函数
Sub的动态代码块执行第1次
为Sub类赋默认值
Sub的无参构造函数
为Super属性赋默认值
Super的动态代码块执行第2次
Super的无参构造函数
Sub的动态代码块执行第2次
为Sub类赋默认值
Sub的无参构造函数

Process finished with exit code 0

     
 */
public class Test00{

    public static void main(String[] args){
        Super s1 = new Sub();
        Super s2 = new Sub();
    }
}

class Super{
    static int countSuper = 0;//动态代码块的 计数器
    Super(){//无参构造
        System.out.println("Super的无参构造函数");
    }
    int sup = Super.getNumber();//Super类赋默认值
    //动态代码块
    {
        System.out.println("Super的动态代码块执行第"+(++countSuper)+"次");
    }
    static int countStaticSuper = 0;
    static {
        System.out.println("Super的静态代码块执行第"+(++countStaticSuper)+"次");
    }
    //为属性赋默认值做标记
    public static int getNumber(){
        System.out.println("为Super属性赋默认值");
        return 0;
    }




}
class Sub extends Super{
   static int countSub = 0;//动态代码块的计数器
    {
        System.out.println("Sub的动态代码块执行第"+(++countSub)+"次");
    }
    int sub = Sub.getNumber();//Sub为属性赋默认值

    static int countStaticSub = 0;//静态代码块计数器
    static {
        System.out.println("Sub的静态代码块执行第"+(++countStaticSub)+"次");

    }
    Sub(){
        System.out.println("Sub的无参构造函数");
    }
    //由于静态方法没有多态,可以覆盖
    public static int getNumber(){
        System.out.println("为Sub类赋默认值");
        return 0;
    }


}