Active use of classes: code testing and understanding in various situations

Active use of class:

 

The active use of classes by Java programs means that < clinit > () of the class will be called, that is, the initialization phase of the class will be executed. The situation is as follows:

1. When creating an instance of a class, for example, use the new keyword, or through reflection, cloning, and deserialization;

2. When calling a static method of a class, the bytecode invokestatic instruction is used;

3. When calling the static field of a class or interface (special consideration for the final modifier);

4. Use Java The methods in lang.reflec package reflect the methods of the class: for example: class forName("com.hahaha.Test")

5. Initialize subclasses of a class;

6. If an interface defines a default method, initialize the interface before initializing the class that directly or indirectly implements the interface

7. When the Java virtual machine starts, it is designated as the initialization of the main class (the class containing the main() method);

8. call Java for the first time lang.invoke. An instance of MethodHandle that initializes the class of the method pointed to by MethodHandle

Code test:

I Create an instance of a class

1. new keyword

public class Active1 {
    public static void main(String[] args) {
        User user = new User();
    }
}

class User{
    static {
        System.out.println("call User Initialization of");
    }
}

2. Deserialization

public class Active1 {

    //Serialization process
    @Test
    public void oos(){
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("test.txt"));
            oos.writeObject(new User());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(oos == null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //Deserialization process (validation)
    @Test
    public void ois(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("test.txt"));
            User user = (User) ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        }catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(ois == null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

class User implements Serializable{
    static {
        System.out.println("call User Initialization of");
    }
}

II Call a static method of a class

public class Active1 {
    @Test
    public void test(){
        User.method();
    }
}

class User implements Serializable{
    static {
        System.out.println("call User Initialization of");
    }

    public static void method(){
        System.out.println("Calling a static method of a class");
    }
}

III When calling a static field of a class or interface (special consideration for the final modifier)

The class contains only static, which is carried out in the initialization phase of the class.

For class and interface: static+final, and the explicit assignment of basic data type or String type called by method or constructor is not involved in the display assignment. It is carried out in the preparation phase of the link phase.
public class Active2 {
    @Test
    public void test1(){
        //Only static is included, which is carried out in the initialization phase of the class
        System.out.println(Man.num);
    }
    @Test
    public void test2(){
        //static+final, and the explicit assignment of the basic data type or String type called by the method or constructor is not involved in the display assignment. It is carried out in the preparation phase of the link phase
        System.out.println(Man.num2);
    }
    @Test
    public void test3(){
        //static+final, and the explicit assignment of String type is involved in the display assignment, which is carried out in the initialization stage of the class
        System.out.println(Man.num3);
    }
    @Test
    public void test4(){
        //static+final, and the basic data types involved in the method or constructor call in the display assignment are carried out in the initialization phase of the class
        System.out.println(Man.num4);
    }
}

class Man {
    static {
        System.out.println("call Man Initialization of");
    }
    public static int num = 1;
    public static final int num2 = 1;
    public static final String num3 = new String("123");
    public static final int num4 = new Random().nextInt(10);
}

 

The interface only contains static, which is carried out in the preparation phase of the link phase.

public class Active2 {
    @Test
    public void test1(){
        //Only static is included, which is carried out in the preparation phase of the link phase
        System.out.println(ComA.num);
    }
    @Test
    public void test2(){
        //static+final, and the explicit assignment of the basic data type or String type called by the method or constructor is not involved in the display assignment. It is carried out in the preparation phase of the link phase
        System.out.println(ComA.num2);
    }
    @Test
    public void test3(){
        //static+final, and the explicit assignment of basic data type or String type involving method or constructor call in the display assignment is carried out in the initialization stage of the class
        System.out.println(ComA.num3);
    }
}



interface ComA{
    //When this method is called, the interface is initialized
    public static final Thread t = new Thread(){
        {
            System.out.println("ComA Initialization of");
        }
    };
    public static int num = 1;
    public static final int  num2 = 1;
    public static final int  num3 = new Random().nextInt(10);

}

 

IV Using Java The method in lang.reflec package reflects the method of the class

public class Active1 {
    @Test
    public void test() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.xxx.active.User");
    }
}

class User {
    static {
        System.out.println("call User Initialization of");
    }

}

V Initializes a subclass of a class

public class Active1 {
    @Test
    public void test() {
        new Student();
    }
}

class User {
    static {
        System.out.println("call User Initialization of");
    }

}

class Student extends User{

}

Supplementary notes:
When the Java virtual machine initializes a class, it requires that all its parent classes have been initialized, but this rule does not apply to interfaces.
When initializing a class, the interface it implements is not initialized first
 When initializing an interface, its parent interface is not initialized first
 Therefore, a parent interface is not initialized because of the initialization of its child interface or implementation class. Only when the program uses the static field of a specific interface for the first time will it cause the initialization of the interface

Vi Interface defines the default method

The default method is defined and the implementation interface is initialized

public class Active2 {
    @Test
    public void test1(){
        new Use();
    }

}

class Use implements ComA{

}

interface ComA {
    //When this method is called, the interface is initialized
    public static final Thread t = new Thread(){
        {
            System.out.println("ComA Initialization of");
        }
    };
    public default void method(){
        System.out.println("Default method called");
    }
}

The default method is not defined, and the implementation interface cannot be initialized

public class Active2 {
    @Test
    public void test1(){
        new Use();
    }

}

class Use implements ComA{

}

interface ComA {
    //When this method is called, the interface is initialized
    public static final Thread t = new Thread(){
        {
            System.out.println("ComA Initialization of");
        }
    };
}

VII Specifies the initialization of the main class (the class that contains the main() method)

class Use {
    static {
        System.out.println("The main class is initialized");
    }
    public static void main(String[] args) {

    }
}

VIII Initialize the class of the method pointed to by MethodHandle

 

Tags: Java

Posted by ravensshade on Fri, 15 Apr 2022 23:58:14 +0930