The difference between Class.forName and ClassLoader.loadClass
Class loading
In order to clarify the differenceClass.forName和ClassLoader.loadClass, first we need to understand the steps of class loading in JVM. Class loading can be divided into the following steps
Loading: Get the binary stream of the class through its fully qualified name, and then load it into the JVM
Verification: Ensure that the information contained in the byte stream of the Class file meets the requirements of the virtual machine and will not endanger the security of the virtual machine
Preparation: Allocate memory space for class variables and set the initial value of the class variable
Analysis
Initialization: Initialize fields and other resources according to user-specified code, executing static blocks.
Class.forName
When we pass:
Class.forName("com.test.MyObj")
When getting a Class, it is actually equivalent to callingClass.forName(className, true, currentLoader). The second parameter of this method indicates whether the class needs to be initialized. We set it totrue, so when Class.forName obtains the Class object, it will automatically initialize the class.Class.forName(className, true, currentLoader), 这个方法的第二个参数表示是否需要初始化类. 我们设置为true, 因此 Class.forName 获取到 Class 对象时, 会自动对类进行初始化的. 并且 Class.forName 加载类的 ClassLoader 和调用Class.forNameAnd Class.forName loads the ClassLoader of the class and the ClassLoader of the class whereClass.forNameis called Same.
ClassLoader.loadClass
Different fromClass.forName,ClassLoader.loadClassdoes not initialize the class by default, that is, theinitializationstep of class loading is not executed, so Static code blocks in the class will not be executed.Class.forName不同, 默认情况下ClassLoader.loadClass并不会初始化类, 即类加载的初始化步骤没有执行, 因此类中的静态代码块不会执行. 并且使用ClassLoader.loadClassAnd when usingClassLoader.loadClass, we can specify a different ClassLoader. For example:
public class MyObj { static { System.out.println("MyObj class init."); } }
public class Test implements Cloneable, Serializable { public static void main(String[] args) throws Exception { Class.forName("com.test.MyObj"); // ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj"); } }
So in the above code,Class.forName("com.test.MyObj")的调用会触发 MyObj 的静态代码块的执行, 而ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj");will not.
What are the benefits of using it this way?
My personal guess is that it should be related to Spring IoC's Lazy loading. In order to speed up the initialization, Spring IoC uses a lot of delayed loading technology. Using classloader does not need to execute the initialization code in the class, which can speed up the loading speed. The initialization work is left until the actual use of this class.
The difference between Class.forName and ClassLoader.loadClass
Class loading
In order to clarify the difference
Class.forName
和ClassLoader.loadClass
, first we need to understand the steps of class loading in JVM.Class loading can be divided into the following steps
Loading: Get the binary stream of the class through its fully qualified name, and then load it into the JVM
Verification: Ensure that the information contained in the byte stream of the Class file meets the requirements of the virtual machine and will not endanger the security of the virtual machine
Preparation: Allocate memory space for class variables and set the initial value of the class variable
Analysis
Initialization: Initialize fields and other resources according to user-specified code, executing static blocks.
Class.forName
When we pass:
When getting a Class, it is actually equivalent to calling
Class.forName(className, true, currentLoader)
. The second parameter of this method indicates whether the class needs to be initialized. We set it totrue
, so when Class.forName obtains the Class object, it will automatically initialize the class.Class.forName(className, true, currentLoader)
, 这个方法的第二个参数表示是否需要初始化类. 我们设置为true
, 因此 Class.forName 获取到 Class 对象时, 会自动对类进行初始化的.并且 Class.forName 加载类的 ClassLoader 和调用
Class.forName
And Class.forName loads the ClassLoader of the class and the ClassLoader of the class whereClass.forName
is called Same.ClassLoader.loadClass
Different from
Class.forName
,ClassLoader.loadClass
does not initialize the class by default, that is, theinitialization
step of class loading is not executed, so Static code blocks in the class will not be executed.Class.forName
不同, 默认情况下ClassLoader.loadClass
并不会初始化类, 即类加载的初始化
步骤没有执行, 因此类中的静态代码块不会执行.并且使用
ClassLoader.loadClass
And when usingClassLoader.loadClass
, we can specify a different ClassLoader. For example:An example
So in the above code,
Class.forName("com.test.MyObj")
的调用会触发 MyObj 的静态代码块的执行, 而ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj");
will not.What are the benefits of using it this way?
My personal guess is that it should be related to Spring IoC's Lazy loading. In order to speed up the initialization, Spring IoC uses a lot of delayed loading technology. Using classloader does not need to execute the initialization code in the class, which can speed up the loading speed. The initialization work is left until the actual use of this class.