标题: ClassLoader.loadClass()与Class.forName()的区别
创建: 2020-08-06 11:31 更新: 2020-08-06 16:37 链接: https://scz.617.cn/web/202008061131.txt
参看:
What's the difference between ClassLoader.load(name) and Class.forName(name) - irreputable [2011-07-10] https://stackoverflow.com/questions/6638959/whats-the-difference-between-classloader-loadname-and-class-fornamename
stackoverflow上另有一篇高赞回答同类问题,那篇根本就没说到点上,不看也罢。
多数时候用这两个API:
/ * java.lang.ClassLoader.loadClass(String) : Class / public Class<?> loadClass(String name)
/ * java.lang.Class.forName(String) : Class / public static Class<?> forName(String className)
它们各有一个功能更强大的重载版本:
/ * java.lang.ClassLoader.loadClass(String, boolean) : Class / protected Class<?> loadClass(String name, boolean resolve)
/ * java.lang.Class.forName(String, boolean, ClassLoader) : Class / public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
考虑如下代码:
class X { static { System.out.println( "Init Class X" ); }
int foo ()
{
return 1;
}
Y bar ()
{
return new Y();
}
}
ClassLoader.loadClass( "X", resolve )
若resolve为true,上述代码加载目标类时尝试加载目标类所引用的其他类,就本例 而言,尝试加载Y。若resolve为false,上述代码只会加载X,不会加载Y。直到有人 调用X.bar(),Y才会被加载。
若resolve为true,同时加载Y失败,则加载X亦失败。若resolve为false,即使Y不存 在,仍可加载X。
ClassLoader.loadClass( "X" )
这个public版本内部resolve为false,正合吾意。
ClassLoader.loadClass()仅加载目标类,不对之初始化,不触发
Class.forName( "X", initialize, loader )
若initialize为true,加载目标类后会对之初始化,触发
Class.forName( "X" )
这个版本相当于:
Class.forName ( "X", true, ClassLoader.getClassLoader ( Reflection.getCallerClass() ) )
注意,是相当于,实际调的是native版本Class.forName0()。Class.forName0()内部 会调用ClassLoader.loadClass(),后者更底层。
Class.forName Class.forName0 ClassLoader.loadClass
2020-08-06 15:25 涂改
试了一下关于resolve为true时的情况,发现加载X的时候,并没有去加载Y。验证方 式是采用反射调用loadClass(),把参数resolve设为true,然后在JVM参数中加上 "-verbose:class"打印被加载的类,结果发现只有X被加载的记录。看了一下 resolveClass0()在hotspot中的实现(jvm.cpp的JVM_ResolveClass),发现是个空方 法。是不是我的验证方式有问题啊?
我是在JDK 1.8上测试的,所看hotspot源码也是1.8的,只是小版本有点差别。
2020-08-06 16:43 scz
这是个好问题。前文是irreputable在2011年所写,我并未验证resolve这一部分,仅 仅是翻译了一下。不排除Java版本变化的可能,但我亦未就此查看2011年的JVM实现。 你的实验应该没有问题,稳妥起见,在此附上你的实验记录,以免他人踩坑。