何时对类进行初始化

必须对类进行初始化的情况:

1.无论如何,包含main方法的类总是会被初始化,且总是第一个被初始化

2.初始化类时,如其父类还未初始化,则先触发父类的初始化

  • 执行类构造器方法和类构造函数:

实例化一个类

  1,new

  2,Class.forname("...").newInstance()

  • 仅执行执行类构造器方法:

  访问静态字段或调用类静态方法

    1.(【ClassName】).[类静态变量]

    2.(【ClassName】).[类静态方法]

不触发类初始化的情况:

   1. 当访问一个常量时(final static),不调用类的类构造器,仅仅是访问一个常量

 2. 当子类访问父类的静态变量和方法时,只执行父类的类构造器,当前调用类不初始化

   3. 定义当前类的数组引用时,不初始化当前类

 


 

代码说明:

  用例代码结构:

    

   

   Class_Initialization 类

public class Class_Initialization {
    
    static private int before = 0;
    
    static {
        //static块内按定义顺序决定访问顺序
        //System.out.println("Class_Initialization...static{}...beforeVarK: "+k);
        
        //静态语句块中只能访问到定义在静态语句块之前的变量
        int k = before;
        System.out.println("Class_Initialization...static{}...beforeVarK: "+k);
        //int j = after1; //Cannot reference a field before it is defined
        
        //定义在它之后的变量,在前面的静态语句块可以赋值,但是不能访问
        after2 = 1;
        System.out.println("Class_Initialization...static{}");
        //System.out.println("Class_Initialization...static{}...afterVar: "+after2);
    }
    
    static private int after1 = 0;
    static private int after2 = 0;

    public static void main(String[] args) {
//        Son_clinit.funStatic_Son();
//        Son_clinit.funFinalStatic_Son();
//        Son_clinit.funFinalStatic_Son();
        

//        Son_clinit.funFinalStatic_Parent();
//        System.out.println(Son_clinit.p);
        
//        System.out.println(Son_clinit.I);
//        System.out.println(Son_clinit.s);
        
//        Son_clinit[] Son_clinit_Hub = new Son_clinit[2];
//        System.out.println(Son_clinit_Hub);
        
//        new Parent_clinit();
//        new Son_clinit();
        
        
        try {
            //Class.forName:返回与给定的字符串名称相关联类或接口的Class对象
            //仅是触发类变量
            //Class.forName("corejava.Son_clinit");
            //Class.forName("corejava.Son_clinit").newInstance();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
}

 

  Son_clinit 类

class Son_clinit extends Parent_clinit{
    
    //p = 100; // Syntax error on token "p", VariableDeclaratorId expected after this token
    
    {
        p = 20;
    }
    
    public final static int I = 8; 
    public static int s = p;//
    
    static {
        p = 100;
        //s = 2;
        System.out.println("Son_clinit...static{}");
        System.out.println("Son_clinit...static{}...s = " + s);
        System.out.println("Son_clinit...static{}...p = " + p);
    }
    
    //Cannot reference a field before it is defined
    //static public int s = p;
    
    public Son_clinit() {
        // TODO Auto-generated constructor stub
        System.out.println("Son_clinit()...Constructor");
    }
    
    public void funNostatic_Son() {System.out.println("Son_clinit...funNostatic_Son()");};
    public static void funStatic_Son() {System.out.println("Son_clinit...funStatic_Son()");};
    public final static void funFinalStatic_Son() {System.out.println("Son_clinit...funFinalStatic_Son()");};
}

 

  Parent_clinit 类

class Parent_clinit {
    
    static public int p = 1;
    
    static {
        p = 10;
        System.out.println("Parent_clinit...static{}");
        System.out.println("Parent_clinit...static{}...p: "+p);
    }
    
    //p = 2; // Syntax error on token "p", VariableDeclaratorId expected after this token
    {
        p = 2;
    }
    
    public Parent_clinit() {
        // TODO Auto-generated constructor stub
        System.out.println("Parent_clinit...Constructor");
    }
    
    public void funNostatic_Parent() {System.out.println("Parent_clinit...funNostatic_Parent()");};
    public static void funStatic_Parent() {System.out.println("Parent_clinit...funStatic_Parent()");};
    public final static void funFinalStatic_Parent() {System.out.println("Parent_clinit...funFinalStatic_Parent()");};
}

 

  测试结果及说明:

    执行类构造器方法和类构造函数

new Parent_clinit();

//包含main方法的类总是会被初始化,且总是第一个被初始化
Class_Initialization...static{}...beforeVarK: 0 Class_Initialization...static{}
//执行了父类的类构造器,初始化了类变量和类代码块(被static修饰) Parent_clinit...
static{} Parent_clinit...static{}...p: 10
//执行了父类构造函数 Parent_clinit...Constructor

    new Son_clinit();

Class_Initialization...static{}...beforeVarK: 0
Class_Initialization...static{}
//由于Son_clinit类继承了Parent_clinit类,父类还未初始化,所以先初始化了父类Parent_clinit Parent_clinit...
static{} Parent_clinit...static{}...p: 10
//执行了当前类的类构造器,初始化了类变量和类代码块(被static修饰) Son_clinit...static{} Son_clinit...static{}...s = 10 Son_clinit...static{}...p = 100
//先执行了父类构造函数后执行当前类构造函数 Parent_clinit...Constructor Son_clinit()...Constructor

Class.forName("corejava.Son_clinit").newInstance()

Class_Initialization...static{}...beforeVarK: 0
Class_Initialization...static{}
Parent_clinit...static{}
Parent_clinit...static{}...p: 10
Son_clinit...static{}
Son_clinit...static{}...s = 10
Son_clinit...static{}...p = 100
Parent_clinit...Constructor
Son_clinit()...Constructo 

 

  仅执行执行类构造器方法

 

  //返回与给定的字符串名称相关联类或接口的Class对象
  Class.forName("corejava.Son_clinit") 
Class_Initialization...static{}...beforeVarK: 0
Class_Initialization...static{}
Parent_clinit...static{}
Parent_clinit...static{}...p: 10
Son_clinit...static{}
Son_clinit...static{}...s = 10
Son_clinit...static{}...p = 100

  System.out.println(Son_clinit.p);

Class_Initialization...static{}...beforeVarK: 0
Class_Initialization...static{}
//子类直接访问父类静态变量,只初始化父类,不初始化子类 Parent_clinit...
static{} Parent_clinit...static{}...p: 10 10

  System.out.println(Son_clinit.s);

Class_Initialization...static{}...beforeVarK: 0
Class_Initialization...static{}
//先初始化父类 Parent_clinit...
static{} Parent_clinit...static{}...p: 10
//再初始化子类 Son_clinit...static{} Son_clinit...static{}...s = 10 Son_clinit...static{}...p = 100
//最后输出变量结果 10

  Son_clinit.funStatic_Parent();

Class_Initialization...static{}...beforeVarK: 0
Class_Initialization...static{}
//子类直接调用父类静态方法,只初始化父类,不初始化当前类 Parent_clinit...
static{} Parent_clinit...static{}...p: 10 Parent_clinit...funStatic_Parent()

   Son_clinit.funFinalStatic_Parent();

Class_Initialization...static{}...beforeVarK: 0
Class_Initialization...static{}
Parent_clinit...static{}
Parent_clinit...static{}...p: 10
Parent_clinit...funFinalStatic_Parent()

   Son_clinit.funStatic_Son();

Class_Initialization...static{}...beforeVarK: 0
Class_Initialization...static{}
//先初始化父类 Parent_clinit...
static{} Parent_clinit...static{}...p: 10 Son_clinit...static{} Son_clinit...static{}...s = 10 Son_clinit...static{}...p = 100 Son_clinit...funStatic_Son()

 

   不触发类初始化

  System.out.println(Son_clinit.I);

Class_Initialization...static{}...beforeVarK: 0
Class_Initialization...static{}
8

Son_clinit[] Son_clinit_Hub = new Son_clinit[2];
System.out.println(Son_clinit_Hub);

Class_Initialization...static{}...beforeVarK: 0
Class_Initialization...static{}
[Lcorejava.Son_clinit;@15db9742
posted @ 2023-09-16 17:39  bkyvv  阅读(19)  评论(0)    收藏  举报