【发布时间】:2023-01-03 06:28:36
【问题描述】:
我正在阅读 PerfMark 代码并看到一条关于通过在提交中使用反射来避免意外类加载的评论:
if (Boolean.getBoolean("io.perfmark.PerfMark.debug")) {
- Logger.getLogger(PerfMark.class.getName()).log(Level.FINE, "Error during PerfMark.<clinit>", err);
+ // We need to be careful here, as it's easy to accidentally cause a class load. Logger is loaded
+ // reflectively to avoid accidentally pulling it in.
+ // TODO(carl-mastrangelo): Maybe make this load SLF4J instead?
+ Class<?> logClass = Class.forName("java.util.logging.Logger");
+ Object logger = logClass.getMethod("getLogger", String.class).invoke(null, PerfMark.class.getName());
..
}
不太明白这里防止了哪个类被意外加载。根据Class#forName 将导致加载记录器类。据我了解,只有在封闭条件为真时才会加载该类。或者这是我想念的点?
我使用 if 块运行该部分,并在 Logger 类的静态和非静态字段上设置断点。无论使用反射还是直接,它仅在执行调用时才命中断点。当 if 条件为假时,无论如何都不会加载记录器。
【问题讨论】:
-
你只是让你的生活更加困难。
Logger将在开始时与 JRE 中的所有其他内容一起自动(类)加载。 -
我怀疑 PerfMark 代码是以这种方式编码的,以使其与不包含 Logger 的旧版 Java 兼容
-
@CtrlAltDel 您的第一条评论具有很强的误导性:JRE 核心中的所有类都是在类路径上可用在开机。他们没有加载。如果每个类都以这种方式初始化和加载,JVM 启动将花费很长时间! - 你的第二个评论是我最好的猜测。
-
@rzwitserloot 抱歉,这听起来对您有很大的误导性。我的意思是你说的“......可用”
-
我不认为我对“加载”一词的解释是这里的核心问题。无论如何,从稀缺的 cmets 可用(代码本身,以及类似的稀疏提交消息,不幸的是,它没有对此进行扩展,也没有链接到更详细的问题) - 我认为这是不可能的告诉为什么这样做。它当然不是要“避免类负载”,因为它不会。我对该提交发表了评论,要求澄清。
标签: java reflection classloader dynamic-class-creation