Java类加载器何时启动? - java

那里有1000万篇文章和文档,介绍什么是Java类加载器以及如何/ *为什么*编写自己的类加载器...但是它们似乎都在假设一些我找不到简单答案的事情!

我了解类加载器的工作:读取字节码并从中构造一个对象。不同的类加载器这样做的方式有所不同,等等。

但是,不必在自己的代码中针对类加载器API编写代码,也不必编写自己的代码,当ClassLoader自己的代码实际触发时,我很难理解

例如:

public static void main(String[] args) {
    Fizz fizz = new Fizz();
    fuzz.buzz();
}

在这里,我们有一个Fizz对象。在可以实例化Fizz之前,我们需要一个类加载器来启动Fizz.class并将其加载到其缓存中。 这在何时何地发生?!?! 它不在我的代码中,因此必须隐式地位于JRE中。

与该问题相切的是,如果我编写自己的类加载器,例如WidgetClassLoader,并希望对其进行配置以加载我的应用程序的所有类,或者也许仅加载我的Fizz.class,我如何将这个WidgetClassLoader绑定到我的应用程序中,以便知道哪个使用classloader?我的代码是否需要显式调用此类加载器,还是像第一个示例一样是隐式的?提前致谢!

参考方案

您的问题并不像您现在想的那么琐碎。

您的Fizz示例:
Fizz何时加载?这在JLS (Chapter 5.4: Linking)中定义。它没有定义何时加载Fizz,但可以保证可见行为。对于“何时”部分,如果找不到Fizz,则会从访问Fizz的第一条语句中引发异常(Fizz fizz = new Fizz())。我很确定在这种情况下,它将是新的Fizz(),因为表达式的右侧首先被评估。如果您这样写:

Fizz fizz = null;
fizz = new Fizz();

在这种情况下,Fizz fizz = null将已经抛出异常,因为它是首次访问Fizz类。

谁加载Fizz?当必须加载类时,“属于”要求该类的代码的类加载器将用于获取该类。在Fizz示例中,这是使用main方法加载类的类加载器。当然,如果类加载器本身不能加载Fizz,则可以选择委托给其父类加载器。

如何使JVM使用我的ClassLoader?有两种方式,显式或隐式。明确地:您可以通过调用自己的类加载器的方法来加载类。隐式地:当您从已经从类加载器中加载的类中执行代码(含义方法或初始化程序)并且需要在该过程中解析类引用时,将自动使用您的类加载器,因为是由类加载器在其中加载了代码第一名。

Java:线程池如何将线程映射到可运行对象 - java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java DefaultSslContextFactory密钥库动态更新 - java

我有一个使用org.restlet.engine.ssl.DefaultSslContextFactory的现有应用程序和一个在服务器启动时加载的密钥库文件。我有另一个应用程序,该应用程序创建必须添加的证书服务器运行时动态地更新到密钥库文件。为此,我在代码中创建了证书和私钥,然后将其写入到目录。该目录由bash脚本监视,该脚本检查是否有新文件,如果出现,它将…