如何通过Bootstrap classloader编程加载其他类



我知道有一个" bootstrap classloader"加载来自jre/lib(rt.jar等(的所有类。是否可以让我接触此" Bootstrap ClassLoader"以从另一个非Java软件包加载其他类?

我说的是 bootstrap classpath,这与此答案中描述的常规类路径大不相同:我应该在运行时动态加载JARS?

bootstrap class Loader表示为null,例如。调用Class.getClassLoader()时。这可以直接馈送到Class.forName(String,boolean,ClassLoader)

如果参数loader为null,则类是通过Bootstrap类加载器加载的。

因此,您可以尝试使用Class.forName(className,true,null)通过Bootstrap加载器明确加载类,也可以使用Class.forName(className,true,context.getClassLoader())相对于其他类’上下文解决类别,而无需特别案例Bootstrap Loader。


如果要定义由Bootstrap加载器加载的运行时类,则没有标准解决方案。有一种方法sun.misc.Unsafe.defineClass(String, byte, int, int, ClassLoader, ProtectionDomain)允许在特定类加载程序中定义类,该类是一个专有的API,将来可能会消失。

从Java 9开始,有java.lang.invoke.MethodHandles.Lookup.defineClass(byte[]),一种标准方法在其他类的上下文中定义了一个类,但是它需要非标准的方式,例如使用访问替代的反射以获取一个Lookup对象,并具有适当的访问权限的bootstrap加载类,例如java.lang.Object。已经存在现有的Q&用于为其他目的创建这样的Lookup对象,例如这个。不过,这种反射骇客不能保证在以后的版本中工作。

对于Java代理,还可以选择将类文件转载到临时JAR文件中,然后以编程方式将其添加到Bootstrap类路径中,如果不介意这涉及I/O。

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

<</p>

通过bootstrap类加载器加载类的一种回旋方式是这样定义自己的类加载程序:

    ClassLoader bootClassLoader = new ClassLoader(null){};

此类加载程序没有父母,因此它唯一会从中加载类的地方是固有的bootstrap类加载器。

最新更新