1

我有一个 .class 文件,但对 .class 文件一无所知,包括类名、字段或方法。我需要做的是找出有关该类的所有信息并实例化该类的一个对象。

请记住,在调用 getDeclareMethod()、getDeclareFields() 和 getDeclareConstructor() 之后,我们对 .class 文件内部一无所知,我知道它包含一个 String str 字段和一个带有一个 String 参数的 void 方法,该方法试图分配一个名称到变量 str 和一个没有任何参数的纯构造函数。

那么问题是如何实例化一个对象并调用方法将一个String分配给str?当类或方法的声明在同一个文件中时,我知道该怎么做,但是这是一个未知的.class文件,我向你们寻求帮助。

4

4 回答 4

4

首先,您需要将 .class 文件转换为Class对象。您可以使用URLClassLoader.

假设您有 aFile classFile和 a String className

try {
    URLClassLoader classLoader = new URLClassLoader(new URL[]{classFile.toURI().toURL()});
    Class<?> clazz = classLoader.loadClass(className);
} catch (Exception e) {
    // something went wrong..
    e.printStackTrace();
}

现在您将类文件存储在一个Class对象中,但是如何创建其类型的对象并从中调用方法呢? 包的Java 反射java.lang.reflect在这种情况下很有用。

假设您将Class<?>对象存储在名为 的变量clazzString methodName方法名称的 aString toSet和方法参数的 a 中。

try {
    Object instance = clazz.newInstance();
    Method method = clazz.getDeclaredMethod(methodName, String.class);
    method.setAccessible(true);
    method.invoke(instance, toSet);
} catch (Exception e) {
    // something went wrong..
    e.printStackTrace();
}

请注意,如果方法名称未知,则必须创建一种识别方法,这可以通过反射完成,但通过使用字节码注入/修改/分析库检查方法的字节码更稳定作为ASMBCEL。虽然 BCEL 自 2006 年以来就没有更新过,但我个人认为它更容易学习如何使用;但是,ASM 要快得多并且是最新的。

于 2012-05-10T05:04:09.213 回答
0

您可以将该 .class 文件转换为 java 文件,即使用 JAD 对其进行反编译,然后知道 java 文件的来源。

你可以使用这个资源,也可以在 google 上找到更多。

于 2012-05-10T04:52:52.550 回答
0

只需阅读本教程,您就会得到所有答案..

使用 Java 反射

反射是 Java 编程语言中的一个特性。它允许正在执行的 Java 程序检查或“自省”自身,并操纵程序的内部属性。例如,Java 类可以获取其所有成员的名称并显示它们。

于 2012-05-10T04:55:23.097 回答
0

如果您有.class 文件,您可以编写自己的ClassLoader,并使用defineClass 创建一个Class 实例。从那里,您可以获得名称和任何构造函数。如果它有一个 null 构造函数,您只需在 Class 实例上执行 newInstance,否则您需要寻找一个构造函数并将适当的参数传递给构造函数的 newInstance 方法。

于 2012-05-10T04:58:29.813 回答