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

2022-09-01 02:11:38

以下代码之间和之间有什么区别:Class.forNameClassLoader.loadClass

Class theClass = Class.forName("SomeImpl");
SomeImpl impl = (SomeImpl)theClass.newInstance();

Class theClass = ClassLoader.loadClass("SomeImpl");
SomeImpl impl = (SomeImpl)theClass.newInstance();

它们是同义词吗?在某些情况下,一个比另一个更可取吗?使用这两种方法时,该做什么和不该做什么?


答案 1

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)

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


答案 2

肖恩的回答或多或少是正确的,除了一些遗漏/小错误:

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

当通过类加载器的图形类似结构加载时,该案例具有影响,即不使用父级仅首先查找。

  • 类的初始化是在ClassLoader的loadClass中执行的,就像这样:ClassLoader实际上可以跳过解决它,感觉就像,不建议但有可能。if (resolve) resolveClass(c);

使用这两种方法的注意事项是什么?

除非你有非常强烈的想法,为什么你想要,不要直接使用它。在所有其他情况下,请始终依赖 。ClassLoader.loadClass(String)Class.forName(name, true, classLoader)

整体类加载紧挨着一门艺术,它不能用一个简单的答案来涵盖(不是开玩笑的艺术部分)


推荐