gpt4 book ai didi

java - 使用 ClassLoader 和 Class.forName 加载类的区别

转载 作者:IT老高 更新时间:2023-10-28 20:30:33 24 4
gpt4 key购买 nike

以下是 2 个代码片段

第一个使用ClassLoader类加载指定的类

ClassLoader cls = ClassLoader.getSystemClassLoader();
类 someClass = cls.loadClass("TargetClass");

第二个使用 Class.forName() 加载指定的类

Class cls = Class.forName("TargetClass");

上述方法有什么区别。哪个用于哪个目的?

最佳答案

其他答案非常完整,因为它们探索了 Class.forName(...) 的其他重载。 ,并讨论使用不同 ClassLoader 的可能性。

但是他们无法回答您的直接问题:“上述方法之间有什么区别?”,它处理一个特定的过载 Class.forName(...) .他们错过了一个非常重要的区别。 类初始化

考虑以下类:

public class A {
static { System.out.println("time = " + System.currentTimeMillis()); }
}

现在考虑以下两种方法:

public class Main1 {
public static void main(String... args) throws Throwable {
final Class<?> c = Class.forName("A");
}
}

public class Main2 {
public static void main(String... args) throws Throwable {
ClassLoader.getSystemClassLoader().loadClass("A");
}
}

头等舱,Main1 , 运行时会产生一个输出,如

time = 1313614183558

然而,另一个根本不会产生任何输出。这意味着类 A ,虽然已加载,但尚未初始化(即 <clinit> 尚未调用)。其实,你甚至可以在初始化之前通过反射来查询类的成员!

你为什么要关心?

有些类在初始化时执行某种重要的初始化或注册。

例如,JDBC 指定由不同提供者实现的接口(interface)。要使用 MySQL,您通常使用 Class.forName("com.mysql.jdbc.Driver"); .也就是说,您加载并初始化该类。我从未见过该代码,但显然该类的静态构造函数必须在某处使用 JDBC 注册该类(或其他东西)。

如果你这样做了 ClassLoader.getSystemClassLoader().loadClass("com.mysql.jdbc.Driver"); ,您将无法使用 JDBC,因为尽管已加载该类,但尚未初始化(然后 JDBC 将不知道要使用哪个实现,就像您没有加载该类一样)。

所以,这就是你问的两种方法的区别。

关于java - 使用 ClassLoader 和 Class.forName 加载类的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4285855/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com