如何通过编程方式通过bootstrap类加载器加载另一个类?

时间:2018-02-08 16:32:06

标签: java classloader bootclasspath

我知道有一个" bootstrap类加载器"从jre / lib(rt.jar等)加载所有类。是否有可能得到这个" bootstrap类加载器"为了从另一个非java包加载一个额外的类?

我正在谈论 bootstrap 类路径,这与此答案中描述的常规类路径非常不同:How should I load Jars dynamically at runtime?

1 个答案:

答案 0 :(得分:3)

bootstrap类加载器表示为null,例如致电Class.getClassLoader()时。这可以直接提供给Class.forName(String,boolean,ClassLoader)

  

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

因此,您可以尝试使用Class.forName(className,true,null)通过引导加载程序显式加载类,或者使用Class.forName(className,true,context.getClassLoader())解析相对于另一个类'上下文的类,而不必使用特殊情况下的引导加载程序。< / p>

如果要定义运行时类,如果由引导加载程序加载,则没有标准解决方案。方法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对象已经存在Q&amp; A,例如this one。但是,这种反射黑客不能保证在未来版本中有效。

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

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