Java:Class.forName和ClassLoader.loadClass之间的区别

IAm*_*aja 40 java classloader

最近遇到了一些让我思考的代码.有什么区别:

Class theClass = Class.forName("SomeImpl");
SomeImpl impl = (SomeImpl)theClass.newInstance();
Run Code Online (Sandbox Code Playgroud)

和:

Class theClass = ClassLoader.loadClass("SomeImpl");
SomeImpl impl = (SomeImpl)theClass.newInstance();
Run Code Online (Sandbox Code Playgroud)

他们是同义词吗?在某些情况下,是否优先于另一方?使用这两种方法有什么用,有什么用呢?

提前致谢.

Sha*_*aun 18

Class.forName()将始终使用调用者的ClassLoader,而ClassLoader.loadClass()可以指定不同的ClassLoader.我相信Class.forName也会初始化加载的类,而ClassLoader.loadClass()方法不会立即执行此操作(直到第一次使用它才会初始化).

在查看确认我的初始化行为摘要时刚发现这篇文章.看起来这里有您正在寻找的大部分信息:

http://www.javaworld.com/javaworld/javaqa/2003-03/01-qa-0314-forname.html

这种用法很酷,虽然我之前从未使用过它:

Class.forName(String, boolean, ClassLoader)
Run Code Online (Sandbox Code Playgroud)

它允许您指定ClassLoader,boolean参数定义是否应该在加载类时初始化该类.

  • 如果您不提供,它将仅使用调用者的类加载器。在同一篇文章中:“ ...如果选择特定的加载器来加载类对您的设计很重要,则应使用ClassLoader.loadClass()**或在其中添加的forName()的三参数版本Java 2平台标准版(J2SE):“ Class.forName(String,boolean,ClassLoader)”。 (2认同)

bes*_*sss 11

除了少数遗漏/小错误之外,肖恩的答案或多或少是正确的:

  • Class.forName将该类与ClassLoader相关联(无论其他任何父级是否将其加载为实际),因此ClassLoader.findLoadedClass下次成功.这是一个非常非常重要的观点,大多数ClassLoader会尝试Class c = findLoadedClass(name); if (c!=null) return c;绕过整个查找/查找部分的第一个语句.直接调用ClassLoader.load不会将类添加到已加载的类.

当通过类似于ClassLoader的图形结构加载时,该情况具有影响,即不使用父级仅首先查找.

  • 类的初始化是在ClassLoader的loadClass中执行的,代码类似于: if (resolve) resolveClass(c);并且ClassLoader实际上可以跳过解决它感觉,不推荐但可能.

使用这两种方法有什么用,有什么用呢?

除非你非常强烈地了解自己的想法ClassLoader.loadClass(String),否则不要直接使用它.在所有其他情况下,始终依靠Class.forName(name, true, classLoader).

整体课堂装载是艺术的一部分,它不能在一个简单的答案中涵盖(不是开玩笑的艺术部分)