我有一个.class文件,对.class文件一无所知,包括类名,字段或方法。我需要做的是找出关于类的所有内容并实例化该类的对象。
请记住,在调用getDeclareMethod(),getDeclareFields()和getDeclareConstructor()之后,我们对.class文件内部一无所知。我知道它包含String str的字段和带有一个String参数的void方法为变量str和没有任何参数的纯构造函数指定名称。
所以问题是如何实例化一个对象并调用该方法将一个String分配给str?我知道当类或方法的声明在同一个文件中时如何做,但这个是一个未知的.class文件,我求助于你们。
答案 0 :(得分:4)
首先,您需要将.class文件转换为Class
对象。您可以使用URLClassLoader
。
假设您有File classFile
和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.lang.reflect
包的Java reflection在这种情况下很有用。
假设您将Class<?>
对象存储在名为clazz
的变量,方法名称的String methodName
和方法参数的String toSet
中。
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();
}
请注意,如果方法名称未知,则必须创建一种识别它的方法,这可以通过反射来完成,但通过使用字节码注入/修改/检查方法的字节码可以更稳定地完成分析库,例如ASM或BCEL。虽然BCEL自2006年以来一直没有更新,但我个人认为,学习如何使用更容易;但是,ASM速度更快,而且是最新的。
答案 1 :(得分:0)
您可以将.class文件转换为java文件,即使用JAD对其进行反编译,然后知道java文件的来源。
您可以使用this资源,还可以在Google上找到更多资源。
答案 2 :(得分:0)
按照本教程,你会得到所有答案..
Reflection是Java编程语言中的一个特性。它允许执行 Java程序检查或“内省”自己,并操纵内部 程序的属性。例如,Java类可以获得 所有成员的名字并显示它们。
答案 3 :(得分:0)
如果您有.class文件,则可以编写自己的ClassLoader,并使用defineClass创建Class实例。从那里,您可以获得名称和任何构造函数。如果它有一个null构造函数,你只需在Class实例上执行newInstance,否则你需要搜索构造函数并将适当的参数传递给构造函数newInstance方法。