In Java reflection, why is it recommended to use Class.forName() to get the class?

1. Three ways to obtain Class objects in Java reflection

In Java reflection, the entrance of reflection is class, and there are three ways to obtain class

  1. Class.class;
  2. Class.forName();
  3. Object.getClass()

Simple understanding of the three

  1. The form of Class.class will cause the JVM to use the class loader to load the class into memory (provided that the class has not been loaded into memory), without doing the initialization of the class, and returning the Class object.
  2. The form of Class.forName() will load the class and do static initialization of the class, and return the Class object.
  3. The form of object.getClass will statically initialize and non-statically initialize the class, and return the Class object of the class to which the object actually refers to at runtime (because the reference of the child object may be assigned to the reference variable of the parent object) belongs to.

Static initialization refers to initialization when the class is loaded, and non-static initialization is initialization when the new object is initialized.

In the three cases, when the Class object is generated, it will be judged whether this class has been loaded in the memory.

Note: Exception handling is only performed when Class.forName() is used, because Class.forName() needs to load the class path to avoid the situation where it cannot be found.

Two, Class.forName source code analysis

Class.forName(String className); the source code of this method is

@CallerSensitive
public static Class<?> forName(String className) throws ClassNotFoundException {
    Class<?> caller = Reflection.getCallerClass();
    return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}

Class.forName() calls the forName0 method. The second parameter of forName0 is set to true by default. This parameter represents whether to initialize the loaded class. Set to true to initialize the class, which means that the static code block in the class will be executed. As well as the assignment of static constants and other operations.

It can be clearly seen that the Class.forName() method is actually implemented by calling ClassLoader.

ClassLoader follows the parental delegation model and calls the class loader that starts the class loader. The function implemented is to "get a binary byte stream describing this class through the fully qualified name of a class", and then place the binary stream in the JVM after obtaining the binary stream. .

3. Why is it recommended to get Class.forName() for class?

Class.forName(), I believe that when we first encountered it, most of it was when we were learning JDBC.

When using JDBC, the Class.forName() method is usually used to load the database connection driver. This is because it is clearly required in the JDBC specification that the Driver (database driver) class must register itself with the DriverManager.

Take the MySQL driver as an example to explain:

public class Driver extends NonRegisteringDriver implements java.sql.Driver {  

    static {  
        try {  
            java.sql.DriverManager.registerDriver(new Driver());  
        } catch (SQLException E) {  
            throw new RuntimeException("Can't register driver!");  
        }  
    } 
    ... 
}

It can be seen from the source code that the operation of Driver registration to DriverManager is written in a static code block, which is why Class.forName() is used when writing JDBC.

Class.forName() is a way to destroy the parent delegation mechanism when loading the database driver. A third-party class is loaded through the Application ClassLoader, and the parent Bootstrap ClassLoad loader is not used.

In a word, the most important reason why it is recommended to use the Class.forName() method to obtain a Class is that the Class.forName() method does static initialization of the class (the Class.class method does not perform the static initialization of the class; the object.getClass() method although Static initialization is also done, but a new object is needed, which is not very convenient).

 

 

reference:

Briefly talk about your understanding of Class.forName(), Class.class and getClass() in Java?

In Java reflection, the difference between Class.forName and ClassLoader

Guess you like

Origin blog.csdn.net/guorui_java/article/details/114433677