Java 反射机制 之 简单模拟反编译
如何解决参数名是 arg0... 之类,参考: Java8获取参数名及Idea/Eclipse/Maven配置 , 当然如果去反编译Java 自带的类 比如 String 得到的参数还是 arg0... 。
为什么?因为反射机制是对 字节码文件(.class 结尾)操作。而我们使用 String 之类的类是已经编译好的,看 jre 压缩包就能发现。
源码(带注释):
public static void main(String[] args) throws ClassNotFoundException {
StringBuilder sb = new StringBuilder();
//
Class> reflectClass = Class.forName("com.hjx.反射.Field反编译.Person");
// reflectClass.getModifiers() 得到是特定 数字
// 需要用 Modifier.toString() 转为特定 修饰符
sb.append(Modifier.toString(reflectClass.getModifiers()));
sb.append(" class ");
// getName() 获取全称 如:java.lang.String
// getSimpleName() 获取简称 如:String
sb.append(reflectClass.getSimpleName());
sb.append(" {");
// 注意是 getDeclaredFields 而不是 getFields
// 因为 getFields 方法只能获取所有公开的属性
Field[] fields = reflectClass.getDeclaredFields();
for (Field field : fields) {
sb.append("\n\t");
sb.append(Modifier.toString(field.getModifiers()));
sb.append(" ");
sb.append(field.getType().getSimpleName());
sb.append(" ");
sb.append(field.getName());
sb.append(";");
}
sb.append("\n");
// 添加类的构造方法
Constructor[] constructors = reflectClass.getDeclaredConstructors();
for (Constructor constructor : constructors) {
sb.append("\n\t");
sb.append(Modifier.toString(constructor.getModifiers()));
sb.append(" ");
sb.append(reflectClass.getSimpleName());
sb.append(" (");
// 参数类型 数组
Class>[] types = constructor.getParameterTypes();
// 参数名 数组
Parameter[] parameters = constructor.getParameters();
appendParam(sb, types, parameters);
sb.append(")");
sb.append("{}");
}
// 添加类的方法
// getDeclaredMethods getMethods 区别同上
Method[] methods = reflectClass.getDeclaredMethods();
for (Method method : methods) {
sb.append("\n\t");
sb.append(Modifier.toString(method.getModifiers()));
sb.append(" ");
// getReturnType() 返回类型
sb.append(method.getReturnType().getSimpleName());
sb.append(" ");
sb.append(method.getName());
sb.append(" (");
Class>[] types = method.getParameterTypes();
Parameter[] parameters = method.getParameters();
appendParam(sb, types, parameters);
sb.append(")");
sb.append("{}");
}
sb.append("\n}");
System.out.println(sb.toString());
}
// 添加方法参数
private static void appendParam(StringBuilder sb,Class>[] types,Parameter[] parameters){
int num = 0;
for (int i = 0; i < types.length; i++) {
sb.append(types[i].getSimpleName());
sb.append(" ");
sb.append(parameters[i].getName());
sb.append(",");
num++;
}
// 删除多余的 ","
if (num > 0){
sb.deleteCharAt(sb.length()-1);
}
}
Person类 源码:
public class Person {
public void test(String str, int i, char c){}
private String name;
private int age;
private String address;
private String remark;
public Person() {
}
public Person(String name, int age, String address, String remark) {
this.name = name;
this.age = age;
this.address = address;
this.remark = remark;
}
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 String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
", remark='" + remark + '\'' +
'}';
}
private static void test(String[] strs,Object o){
}
}
运行结果:
public class Person {
private String name;
private int age;
private String address;
private String remark;
public Person (String name,int age,String address,String remark){}
public Person (){}
public String toString (){}
public String getAddress (){}
public String getName (){}
public void setName (String name){}
public void test (String str,int i,char c){}
public void setAge (int age){}
public void setAddress (String address){}
public void setRemark (String remark){}
public String getRemark (){}
public int getAge (){}
}