gpt4 book ai didi

Java:给定类加载器和类,获取类字节码

转载 作者:行者123 更新时间:2023-11-29 03:16:00 24 4
gpt4 key购买 nike

我有以下场景,我有一个类加载器和它加载的一个类,现在我需要那个类的字节码。到目前为止,这是我尝试过的:

    Field f = ClassLoader.class.getDeclaredField("classes");
f.setAccessible(true);

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Vector<Class> classes = (Vector<Class>) f.get(classLoader);

for(Class loadedClass : classes)
{
String className = loadedClass.getName();
String classFileResourcePath = "/" + className.replace(".", "/") + ".class";
InputStream inputStream = classLoader.getResourceAsStream(classFileResourcePath);
System.out.println(">>>> " + className + " => " + classFileResourcePath + " => " + inputStream);
}

此代码为每个类文件打印 null。但是,当我将它更改为 classLoader.getClass().getResourceAsStream(classFileResourcePath) 时,如果在 IDE 中的独立主类中运行,它就可以工作,但是当我到达需要它的实际上下文时,这也返回 null,大概是因为 jar 和幕后的类发生了“特殊”的事情。在无法讨论这些细节的情况下,只需说明我拥有的是一个类和加载它的类加载器,现在我需要字节码。我该怎么做呢?如果这在 Java 层中是不可能的,我也许能够获取原始 Jar 本身并将其作为 zip 文件读取,但那将是最后的手段。

最佳答案

您的代码示例实际上存在几个问题:

首先,您访问 java.lang.ClassLoader 类的“classes”字段以确定已经加载了哪些类。这是一个私有(private)字段,如果您让您的代码在使用专门类加载器(java.lang.ClassLoader 的子类)的环境中运行,您或多或少不知道该字段中包含什么。

使用 ClassLoader.getResourceAsStream, 您在路径前加上“/”,这是不正确的。 ClassLoader.getResourceAsStream 需要一个绝对路径并且该路径以第一个段的名称开头,例如使用 ClassLoader.getResourceAsStream("java/lang/ClassLoader.class") 而不是 ClassLoader.getResourceAsStream("/java/lang/ClassLoader.class")

使用 Class.getResourceAsStream,您可以提供以“/”开头的绝对路径,或者提供相对于相关类的路径,而不是以“/”开头。例如。 ClassLoader.class.getResourceAsStream("ClassLoader.class")ClassLoader.class.getResourceAsStream("/java/lang/ClassLoader.class") 通常都会给你访问权限到类的字节码。

然而,这两种方法都需要使用 Java 运行时环境的标准命名约定,将类文件作为类路径上的资源提供。没有要求 Java 运行时环境必须以这种方式运行。 Java 类可能是动态生成的,导致它们被类加载器识别,但不受持久字节代码的支持。专有类加载器也不需要使用与标准类加载器相同的类名和资源路径之间的映射。

Java 类加载器也不提供公共(public) API 来访问类的字节码。如果您将 VM 分为“ native 代码部分”和“Java 代码部分”,那么很明显,VM 通常不需要从“Java 代码部分”引用原始字节码。

依靠标准类加载器使用的约定,您可以使用您的方法,它主要适用于独立应用程序。但是正如您自己发现的那样,如果您在不同的环境中运行代码,它可能会失败,例如部署到应用程序服务器或使用 OSGi 等打包框架时。

关于Java:给定类加载器和类,获取类字节码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26637137/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com