【问题标题】:How to load another class via bootstrap classloader programmatically?如何以编程方式通过引导类加载器加载另一个类?
【发布时间】:2018-02-08 16:32:06
【问题描述】:

我知道有一个“引导类加载器”从 jre/lib(rt.jar 等)加载所有类。是否可以使用这个“引导类加载器”来从另一个非 Java 包加载额外的类?

我说的是 bootstrap 类路径,它与此答案中描述的常规类路径非常不同:How should I load Jars dynamically at runtime?

【问题讨论】:

标签: java classloader bootclasspath


【解决方案1】:

引导类加载器表示为null,例如拨打Class.getClassLoader()时。这可以直接反馈给Class.forName(String,boolean,ClassLoader)

如果参数loader为null,则通过引导类加载器加载类。

因此,您可以尝试使用 Class.forName(className,true,null) 通过引导加载程序显式加载一个类,或者使用 Class.forName(className,true,context.getClassLoader()) 解析相对于另一个类的上下文的类,而无需对引导加载程序进行特殊处理。


如果你想定义一个运行时类,就像被引导加载程序加载一样,没有标准的解决方案。有一个方法 sun.misc.Unsafe.defineClass(String, byte, int, int, ClassLoader, ProtectionDomain) 允许在特定的类加载器中定义一个类,这是一个专有的 API,将来可能会消失。

从 Java 9 开始,有 java.lang.invoke.MethodHandles.Lookup.defineClass(byte[]),一个标准方法在另一个类的上下文中定义一个类,但它需要非标准方法,例如具有访问覆盖的反射以获取具有对引导加载类的适当访问权限的Lookup 对象,例如java.lang.Object。已经存在关于为其他目的创建这样的Lookup 对象的问答,例如this one。但不保证此类反射黑客在未来的版本中有效。

对于 Java 代理,如果不介意这涉及 I/O,还可以选择将类文件转储到临时 Jar 文件和 add it to the bootstrap class path 中。

还有一个需要注意的问题。当您希望其他引导加载的类找到您的类时,您必须在第一次尝试访问该类之前添加它,因为 JVM 的解析器会记住结果,即使它因错误而失败。

【讨论】:

  • “将类加载到引导类路径中”这句话没有多大意义。您可以将 jar 文件添加到引导类路径,但不能添加单个类。如果你想强制创建一个运行时类,就好像通过引导类加载器加载一样,没有标准的 API,只有 hacks。
  • @LatencyFighter 关于系统类加载器的另一个问题很容易回答,因为那时存在一个现有的ClassLoader 实例,而不是null 代表的引导类加载器。诚然,我有点惊讶 Java 代理没有这样的选项来简单地定义一个类,但是,我扩展了我的答案并列出了我目前知道的所有选项。
  • @FrancescoMenzani 这是你不应该做的事情。您不应该将普通应用程序类添加到引导加载程序。除此之外,使用Class.forName(…) 进行反射类加载,然后使用new MyClass() 之类的非反射使用是没有意义的。后者已经加载了类。
  • @FrancescoMenzani new MyClass() 将询问应用程序类加载器,后者将首先询问父加载器,因此如果该类位于引导路径上,它将由引导加载器加载。首先反射加载它不会影响该逻辑。操作引导类加载路径的选项are documented...
  • @hagrawal 如果您的类仅通过普通类路径(或模块路径)提供,则引导加载程序不可见。所以是的,在这些正常情况下,您无法使用引导加载程序加载您的类。通常情况下,没有必要。
【解决方案2】:

通过引导类加载器加载类的一种有点迂回的方法是定义自己的类加载器,如下所示:

    ClassLoader bootClassLoader = new ClassLoader(null){};

这个类加载器没有父类,因此它加载类的唯一位置是固有的引导类加载器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多