Lat*_*ter 3 java classloader bootclasspath
我知道有一个“引导类加载器”从 jre/lib(rt.jar 等)加载所有类。是否有可能让我使用这个“引导类加载器”以便从另一个非 java 包加载额外的类?
我说的是引导程序类路径,它与此答案中描述的常规类路径非常不同:我应该如何在运行时动态加载 Jars?
引导类加载器表示为null,例如,在调用时Class.getClassLoader()。这可以直接提供给Class.forName(String,boolean,ClassLoader):
如果参数
loader为空,则通过引导类加载器加载该类。
因此,您可以尝试通过引导加载程序显式加载一个类,使用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为其他目的创建这样一个对象的问答,例如这个。但是,不能保证此类 Reflection hack 在未来版本中有效。
对于 Java 代理,如果不介意这涉及 I/O ,还可以选择将类文件转储到临时 Jar 文件中并以编程方式将其添加到引导类路径。
还有一个要注意的问题。当您希望其他引导加载的类找到您的类时,您必须在第一次尝试访问该类之前添加它,因为 JVM 的解析器会记住结果,即使它会因错误而失败。