The running process and reflection of java program

introduction

  • Everything in the world has its own "foundation". The foundation of the tree lies in the root, the foundation of the building lies in the frame, the key to being a man lies in virtue, and the key to being a government lies in the people. In fact, to some extent, "basic" and "required" It can be called the same root and the same branch. They mean the same thing. Then we must not only think, but what are the "base" and "must" of Java? In fact, we can answer without hesitation that this is "reflection", and the secret of reflection will be gradually revealed below.

The running process of java program

  • Before learning reflection, we must first learn the process of running java programs. When the program wants to use a certain class, the system will initialize the class through the three steps of class loading, class connection, and class initialization. If there is no unexpected situation, the JVM will complete these three steps continuously.

Class loading

Class loading refers to reading a class file into memory and creating a java.lang.Class object for it. When any class is used, the system will create a java.lang.Class object for it.
The class loading process generally goes through three processes.
1. Obtain the binary byte stream defined by a class through its fully qualified name (get stream)
2. Convert the static storage structure represented by this byte stream into the runtime data structure of the method area (method area).
3. Generate a java.lang.Class object representing this class in the Java heap as the access entry to the data in the method area (generate access entry).

link

The link is divided into three phases.
1. The verification phase: It is used to verify whether the loaded class has the correct internal structure and is consistent with other classes.
2. Preparation stage: Responsible for allocating memory for class variables and setting default initialization values.
3. Parsing stage: Replace symbol references in the binary data of the class with direct references.

verification:

Verification is the first step of the link. The purpose of this stage is to ensure that the information contained in the byte stream of the Class file meets the requirements of the current virtual machine and does not endanger the security of the virtual machine itself. The verification phase will roughly complete 4 phases of verification action
file format verification: verify whether the byte stream meets the specifications of the Class file format; for example: whether it starts with 0xCAFEBABE, whether the major and minor version numbers are within the processing range of the current virtual machine, constant Whether the constants in the pool have unsupported types.
Metadata verification: perform semantic analysis on the information described by the bytecode (note: compare the semantic analysis at the javac compilation stage) to ensure that the information described meets the requirements of the Java language specification; for example: this class except java.lang.Object Whether there is a parent class outside.
Bytecode verification: Through data flow and control flow analysis, it is determined that the program semantics are legal and logical.
Symbol reference verification: to ensure that the parsing action can be executed correctly.
The verification phase is very important, but not necessary. It has no effect on the program runtime. If verification is not required, you can consider using the -Xverifynone parameter to turn off most of the class verification measures to shorten the virtual machine class loading time.

initialization

Assign the correct initial value to the static variables of the class, and the JVM is responsible for initializing the class, mainly to initialize the class variables. There are two ways to initialize class variables in Java:
1. Declaring class variables is to specify the initial value.
2. Use static code blocks to specify initial values ​​for class variables.
The steps of class initialization or JVM initialization are as follows:
1) If this class has not been loaded and linked, load and link first;
2) If this class has a direct parent class, and this class has not been initialized (note: In a class loader, the class can only be initialized once), then directly initialize the parent class (not applicable to interfaces);
3) If there are initialization statements in the class (such as static variables and static blocks), then perform these initializations in turn Statement.

java class loader

The main role of the java class loader is to load the .class file into memory and generate the corresponding java.lang.Class object for it.

JVM class loader

Overall responsibility: when a class loader is responsible for loading a class, other classes that the class depends on and referenced will also be loaded by the class loader, unless another class loader is used to load it.
Parent class delegation: When a class loader is responsible for loading a class, first let the parent class loader try to load the class, and only try to load the class from its own class path when the parent class loader cannot load the class .
Cache mechanism: **Ensure that all loaded Class will be cached. When the program needs to use a Class object, the class loader first searches for the Class in the cache area. Only when the Class object does not exist in the cache area, the system Only then will the binary data corresponding to this class be read, converted into a Class object, and stored in the buffer.

Built-in class loader in Java

Bootstrap class loader: It is the built-in class loader of the virtual machine, which is usually represented as null and has no parent loading class.
Platform class loader: The platform class loader can see all platform classes. The platform class includes the JavaSE platform API defined by the platform class loader or its ancestors, its implementation class and the JDK-specific runtime class
System class loader: it is also called It is the application class loader, which is different from the platform class loader. System class loader is usually used to define
the inheritance relationship of application class path, module path and class class loader on JDK specific tools : the parent loader of System is Platform, and the parent loader of Platform is Bootstrap.

reflection

Reflection refers to obtaining a class's variables and method information (member methods and construction methods) at runtime. Then create an object based on the obtained information, which is a mechanism for calling methods. Due to this dynamic nature, the flexibility of the program can be greatly enhanced. The program does not need to be determined during the compilation period, and can still be expanded during the runtime. The following is a simple reflection diagram.
In fact, a little reflection of grounding gas is to encapsulate the various parts of a class into other objects
Insert picture description here
. The schematic diagram of a simple reflection example,
Insert picture description here
whether it is the Student class or the Teacher class, is obtained through the reflection mechanism at runtime to obtain the information of these two classes to create a new The rule object.

Case number one

1. Configure the reflection file by loading the properties file.
Entity class

public class Student {
    
    
    private String username;
    private String age;
    private String gender;
    private String address;
    private String phone;

    public Student() {
    
    
    }

    public Student(String username, String age,
                   String gender, String address, String phone) {
    
    
        this.username = username;
        this.age = age;
        this.gender = gender;
        this.address = address;
        this.phone = phone;
    }

    public String getUsername() {
    
    
        return username;
    }

    public Student setUsername(String username) {
    
    
        this.username = username;
        return this;
    }

    public String getAge() {
    
    
        return age;
    }

    public Student setAge(String age) {
    
    
        this.age = age;
        return this;
    }

    public String getGender() {
    
    
        return gender;
    }

    public Student setGender(String gender) {
    
    
        this.gender = gender;
        return this;
    }

    public String getAddress() {
    
    
        return address;
    }

    public Student setAddress(String address) {
    
    
        this.address = address;
        return this;
    }

    public String getPhone() {
    
    
        return phone;
    }

    public Student setPhone(String phone) {
    
    
        this.phone = phone;
        return this;
    }


    //成员方法:一个私有,四个公共
    private void function() {
    
    
        System.out.println("function");
    }
    public void method1() {
    
    
        System.out.println("method");
    }
    public void method2(String s) {
    
    
        System.out.println("method:" + s);
    }
    public String method3(String s, int i) {
    
    
        return s + "," + i;
    }
    public void study() {
    
    
        System.out.println("好好学习天天向上");
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "username='" + username + '\'' +
                ", age='" + age + '\'' +
                ", gender='" + gender + '\'' +
                ", address='" + address + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }
}
public class Teacher {
    
    
    public void teach() {
    
    
        System.out.println("为国育人");
    }
}

Test class

public class Demo02Test {
    
    

    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, IOException, InstantiationException, NoSuchMethodException, ClassNotFoundException {
    
    
        ReflectTest();
    }

    public static void ReflectTest() throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
    
    

        System.out.println("------------------------------------");
        //BufferedReader bufferedReader = new BufferedReader(new FileReader("reflect\\myproperties.properties"));
        FileReader fileReader = new FileReader("G:\\javaEE\\javaTEST\\newfeature\\src\\reflect\\myproperties.properties");
        Properties properties = new Properties();
        properties.load(fileReader);
        fileReader.close();
        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");


        Class<?> aClass = Class.forName(className);
        Constructor<?> constructor = aClass.getConstructor();
        Object o = constructor.newInstance();

        Method method = aClass.getMethod(methodName);
        method.invoke(o);
        System.out.println("---------------------------------");
    }
}

properties file

className=reflect.domain.Teacher
methodName=teach

Test result
Insert picture description here
After modifying the configuration file, the test result is as follows:

className=reflect.domain.Student
methodName=study

Insert picture description here

Case two

Transmit the student instance object to the user instance object.
Entity class

public class User {
    
    
    private String username;
    private String age;
    private String gender;
    private String address;
    private String phone;

    public User() {
    
    
    }

    public User(String username, String age,
                String gender, String address, String phone) {
    
    
        this.username = username;
        this.age = age;
        this.gender = gender;
        this.address = address;
        this.phone = phone;
    }

    public String getUsername() {
    
    
        return username;
    }

    private User setUsername(String username) {
    
    
        this.username = username;
        return this;
    }

    public String getAge() {
    
    
        return age;
    }

    private User setAge(String age) {
    
    
        this.age = age;
        return this;
    }

    public String getGender() {
    
    
        return gender;
    }

    private User setGender(String gender) {
    
    
        this.gender = gender;
        return this;
    }

    public String getAddress() {
    
    
        return address;
    }

    private User setAddress(String address) {
    
    
        this.address = address;
        return this;
    }

    public String getPhone() {
    
    
        return phone;
    }

    private User setPhone(String phone) {
    
    
        this.phone = phone;
        return this;
    }
    @Override
    public String toString() {
    
    
        return "User{" +
                "username='" + username + '\'' +
                ", age='" + age + '\'' +
                ", gender='" + gender + '\'' +
                ", address='" + address + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }
}

Reflection tools

public class MyReflectUtils {
    
    
    public static <T> T MyReflectMethod(HashMap<String ,String> hashMap, Class<T> cls){
    
    
        T t = null;

        try {
    
    
            t = cls.newInstance();
            Field[] declaredFields = cls.getDeclaredFields();
            for (Field field:
                 declaredFields) {
    
    
                 field.setAccessible(true);
                System.out.println(field.toString());

            }
            Method[] methods = cls.getDeclaredMethods();
            for (Method method :
                    methods) {
    
    
                method.setAccessible(true);
                String methodName = method.getName();
                if(methodName.startsWith("set")){
    
    
                    String subName = methodName.substring(3);
                    String firstchar = subName.substring(0, 1);
                    firstchar=firstchar.toLowerCase();
                    String actMethodName= firstchar+subName.substring(1);
                    String value = hashMap.get(actMethodName);
                    try {
    
    
                        method.invoke(t,value);
                    } catch (InvocationTargetException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        } catch (InstantiationException e) {
    
    
            e.printStackTrace();
        } catch (IllegalAccessException e) {
    
    
            e.printStackTrace();
        }
        return t;
    }



    /*public static User MyReflectMethod1(HashMap<String,String> hashMap){
        User user = new User();
        //获取姓名时一定要精确匹配,不然就运行不出结果
        String username =hashMap.get("username ");
        String age      =hashMap.get("age      ");
        String gender   =hashMap.get("gender   ");
        String address  =hashMap.get("address  ");
        String phone    =hashMap.get("phone    ");

        user.setAddress(address).setAge(age).
                setUsername(username).setGender(gender).setPhone(phone);
        return user;
    }
    public static Student MyReflectMethod2(HashMap<String,String> hashMap){
        Student student = new Student();
        String username =hashMap.get("username");
        String age      =hashMap.get("age");
        String gender   =hashMap.get("gender");
        String address  =hashMap.get("address");
        String phone    =hashMap.get("phone");

        student.setAddress(address).setAge(age).
                setUsername(username).setGender(gender).setPhone(phone);
        return student;
    }*/
}

Test class

public class Reflect01Demo {
    
    
    public static void main(String[] args) {
    
    
        Map map = new HashMap<String,String>();
        map.put("username","甄志丙");
        map.put("age","18");
        map.put("gender","男");
        map.put("address","终南山");
        map.put("phone","110");
        Student student1 = MyReflectUtils.MyReflectMethod((HashMap<String, String>) map, Student.class);
        System.out.println(student1);
        User user1 = MyReflectUtils.MyReflectMethod((HashMap<String, String>) map, User.class);
        System.out.println(user1);
    }
}

Test Results
Insert picture description here

Advantages of reflection

Think through the above cases. Why is reflection the soul of the framework?
1) Reflection provides a feasible method for the program to operate the target object during the running process, which greatly improves the flexibility of the program.
2) The decoupling of the program is enhanced based on the reflection mechanism, the coupling is reduced, and the program scalability is enhanced.
So far, the reflection case review is complete.

Guess you like

Origin blog.csdn.net/xueshanfeitian/article/details/108975400