
标题: ClassLoader.loadClass()与Class.forName()的区别
创建: 2020-08-06 11:31
更新:
链接: http://scz.617.cn:8/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()仅加载目标类,不对之初始化,不触发<clinit>。可以对被加载后的目标类进行反射操作,遍历构造函数、方法、成员等等。
Class.forName( "X", initialize, loader )
若initialize为true,加载目标类后会对之初始化,触发<clinit>,静态代码块被执行,就本例而言,会输出"Init Class X"。若initialize为false,加载目标类后不对之初始化,不触发<clinit>。
Class.forName( "X" )
这个版本相当于:
Class.forName
(
"X",
true,
ClassLoader.getClassLoader
(
Reflection.getCallerClass()
)
)
注意,是相当于,实际调的是native版本Class.forName0()。Class.forName0()内部会调用ClassLoader.loadClass(),后者更底层。
Class.forName
Class.forName0
ClassLoader.loadClass
文章转载自青衣十三楼飞花堂,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




