在上一篇文章中,已经详细的介绍了Java的反射机制,没看过的小伙伴可以去我的上一篇文章看一下,相信你一定有所收获。
上一篇文章地址:反射的详细介绍
首先我们再来回顾一下Java的反射机制。
什么是反射机制?
在程序运行状态中,对于任意一个类或对象,都能够获取到这个类的所有属性和方法(包括私有属性和方法),这种动态获取信息以及动态调用对象方法的功能就称为反射机制。简单来讲,通过反射,类对我们是完全透明的,想要获取任何东西都可以。
反射机制的优点:
- 可以在程序运行过程中,操作这些对象;
- 可以解耦,提高程序的可扩展性。
今天我们就使用反射机制来实现反编译的功能。
什么是反编译?
反编译就是把*.class 文件逆向生成*.java文件。
代码演示:
首先我们需要一个*.class 文件,内容如下所示:
public class Worker implements Person{
public String name;
public int age;
private String address;
public Worker() {
}
public Worker(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public void eat(){
System.out.println("eat...");
}
private void play(){
System.out.println("play...");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
使用代码实现反编译:
public class DecompilationDemo {
public static void main(String[] args) throws Exception {
//获取Person的Class对象
Class cls= Class.forName("zzuli.edu.exercise.Worker");
//获取包名
Package packageName=cls.getPackage();
System.out.println(packageName);
//获取类的权限修饰符 public:1 private:2
int modifiers= cls.getModifiers();
//把int类型的权限修饰符转换为String类型
String modifier=Modifier.toString(modifiers);
System.out.print(modifier);
//获取类名
String className=cls.getSimpleName();
System.out.print(" class "+className);
//获取继承的父类
String parentClassName=cls.getSuperclass().getSimpleName();
System.out.print(" extends "+parentClassName);
//获取实现的接口
System.out.print(" implements ");
Class[] interfaces=cls.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
System.out.print(interfaces[i].getSimpleName());
if(i<interfaces.length-1){
System.out.print(" , ");
}
}
System.out.println(" { ");
System.out.println("=========获取成员变量==========");
//获取所有的成员变量
Field[] fields = cls.getDeclaredFields();
for (int i = 0; i <fields.length ; i++) {
//获取成员变量的修饰符
String fieldModifier =Modifier.toString(fields[i].getModifiers());
System.out.print(" " + fieldModifier+" ");
//获取成员变量的限定名
String fieldName=fields[i].getType().getSimpleName();
System.out.print(fieldName+" ");
//获取成员变量的自定义名
String name=fields[i].getName();
System.out.println(name+" ;");
}
System.out.println("=========获取构造器==========");
//获取构造器
Constructor[] constructors=cls.getDeclaredConstructors();
for (int i = 0; i < constructors.length; i++) {
//获取构造器的权限修饰符
String constructorModifier =Modifier.toString(constructors[i].getModifiers());
System.out.print(" " + constructorModifier+" ");
//在Constructor中无法直接获取构造器的限定名,但是构造器的限定名和类名一样,所以可以直接使用类名
System.out.print(className+"(");
//获取构造器的所有参数
Class[] prams=constructors[i].getParameterTypes();
for (int j = 0; j <prams.length ; j++) {
String pramName=prams[j].getSimpleName();
System.out.print(pramName+" args"+j);
if(j <prams.length-1){
System.out.print(" , ");
}
}
System.out.print(")");
System.out.println("{}");
}
System.out.println("=========获取成员方法==========");
// 获取所有成员方法
Method[] methods = cls.getDeclaredMethods();
for (int i = 0; i < methods.length ; i++) {
//获取方法的权限修饰符
String methodModifier =Modifier.toString(methods[i].getModifiers());
System.out.print(" " + methodModifier+" ");
//获取方法的限定名
String methodSimpleName=methods[i].getReturnType().getSimpleName();
System.out.print(methodSimpleName+" ");
//获取自定义的的方法名
String methodName=methods[i].getName();
System.out.print(methodName);
System.out.print("(");
//获取所有参数
Class[] prams=methods[i].getParameterTypes();
for (int j = 0; j <prams.length ; j++) {
String pramName=prams[j].getSimpleName();
System.out.print(pramName+" args"+j);
if(j <prams.length-1){
System.out.print(" , ");
}
}
System.out.print(")");
System.out.println("{}");
}
}
}
运行结果: