关于什么是 Java类加载器,有1000万篇文章和文档,以及如何**为什么*编写自己的...但他们似乎都在假设一些我找不到简单答案的东西!
我理解类加载器的工作:读取字节码并从中构造一个对象.不同的类加载器以不同的方式执行此操作
但是从来没有必须在我自己的代码中对类加载器API进行编码,而且从不必编写我自己的代码,我很难理解当ClassLoader自己的代码实际触发时.
例如:
public static void main(String[] args) {
Fizz fizz = new Fizz();
fuzz.buzz();
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们有一个Fizz对象.在Fizz可以实例化之前,我们需要一个类加载器来启动并加载Fizz.class到其缓存中.这种情况何时何地发生?!?!它没有明确地出现在我的代码中所以它必须隐含在JRE中的某个地方......?
与这个问题相切,如果我编写自己的类加载器,WidgetClassLoader并且想要将其配置为加载我的所有应用程序的类,或者可能只是我的Fizz.class,我如何将其"绑定" WidgetClassLoader到我的应用程序中,以便它知道要使用哪个类加载器?我的代码是否需要显式调用此类加载器,还是像第一个示例一样隐式?提前致谢!
你的问题并不像你现在想象的那么简单.
你的Fizz例子:Fizz什么时候加载?这在JLS(第5.4章:链接)中定义.它没有定义何时加载Fizz,但它保证了可见行为.对于'when'部分,如果找不到Fizz,则会从访问Fizz的第一个语句(Fizz fizz = new Fizz())中抛出异常.我很确定在这种情况下它将是新的Fizz(),因为表达式的右侧首先被评估.万一你写的像这样:
Fizz fizz = null;
fizz = new Fizz();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Fizz fizz = null将抛出异常,因为它是第一次访问Fizz类.
谁加载Fizz?当必须加载类时,使用"属于"需要该类的代码的类加载器来获取该类.在Fizz示例中,这将是使用main方法加载类的类加载器.当然,如果类加载器无法自行加载Fizz,则可以选择委托其父类加载器.
如何让JVM使用我的 ClassLoader?有两种方式,明确或隐含.明确地说:您可以通过调用其方法通过您自己的类加载器加载类.Implcitly:当你执行代码(指方法或初始化)来自已从您的类加载器和类引用需要加载的过程中需要解决的一类,你的类加载器会自动使用,因为它是加载代码的类加载器第一名.