Java中loadClass("全限定类名")与<ClassName>.class.getDeclaredConstructors的区别
Java中ClassLoader.loadClass()与直接使用.class的区别及代码分析
咱们先把ClassLoader.loadClass("全限定类名")和直接用
一、两者的核心区别
- 类初始化时机不一样:
ClassLoader.loadClass()走的是*延迟加载(懒加载)*路子——它只会把类的元数据加载到JVM,但不会触发类的初始化(比如静态代码块、静态变量赋值这些逻辑都不会执行),只有当你第一次调用newInstance()创建实例,或者主动访问类的静态成员时,才会完成初始化。- 而直接写
<ClassName>.class就不一样了,代码执行到这一行的时候,JVM会立刻完成类的加载、链接、初始化全流程,静态代码块啥的直接就跑起来了。
- 类加载器的可控性不同:
ClassLoader.loadClass()可以指定用哪个类加载器来加载类,比如示例里用的是ClassloadersExample对应的应用类加载器,你要是自定义了类加载器,也能切换着用,灵活性拉满。<ClassName>.class是JVM自动用加载当前类的类加载器来加载目标类,开发者没法手动指定其他加载器,属于“全自动”模式。
- 异常类型有区别:
ClassLoader.loadClass()会抛出ClassNotFoundException,这是检查型异常,必须显式捕获或者在方法上声明抛出。- 用
<ClassName>.class如果找不到类,会抛出NoClassDefFoundError,这属于运行时错误,不需要提前捕获。
二、示例代码的执行逻辑分析
先把示例里没写完的代码补全成合理的样子,方便咱们分析:
class testMe{ static { System.out.println("testMe类初始化"); } void show(){ System.out.println("Hello"); } } public class ClassloadersExample { public static void main(String args[]) { ClassLoader c = ClassloadersExample.class.getClassLoader(); //Line 1 try { Class c1 = c.loadClass("test.testMe"); // Line 2 Constructor a[] = c1.getDeclaredConstructors(); for (Constructor constructor : a) { testMe m = (testMe)constructor.newInstance(); m.show(); } Constructor con[] = testMe.class.getDeclaredConstructors(); // Line 6 for (Constructor constructor : con) { testMe m = (testMe)constructor.newInstance(); m.show(); } } catch (Exception e) { e.printStackTrace(); } } }
接下来一步步看执行流程:
- Line 1:获取加载
ClassloadersExample的类加载器,默认是应用类加载器(AppClassLoader),负责加载classpath下的类文件。 - Line 2:调用
loadClass("test.testMe")加载testMe类,这一步只完成类的加载+链接,不会触发testMe的静态代码块,所以此时不会输出"testMe类初始化"。 - 遍历构造方法并实例化:调用
c1.getDeclaredConstructors()拿到testMe的所有构造方法(这里只有默认无参构造),然后调用constructor.newInstance()创建实例——这一步会触发testMe的类初始化,所以第一次执行时会先输出"testMe类初始化",接着调用show()输出"Hello"。 - Line 6及后续:直接用
testMe.class.getDeclaredConstructors()获取构造方法,这时候testMe已经在之前的实例化过程中完成了初始化,JVM不会重复执行类初始化逻辑。所以遍历构造方法创建实例时,只会直接调用show()输出"Hello",不会再输出静态代码块的内容。
⚠️ 注意:如果testMe实际所在的包不是test,Line2会抛出ClassNotFoundException,所以要确保全限定类名和实际包结构一致。
内容的提问来源于stack exchange,提问作者Neha
相关产品推荐
相关产品推荐

