zoukankan      html  css  js  c++  java
  • 使用反射机制实现反编译

    在上一篇文章中,已经详细的介绍了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("{}");
            }
        }
    }
    

    运行结果:
    在这里插入图片描述

  • 相关阅读:
    POJ 3630 Phone List/POJ 1056 【字典树】
    HDU 1074 Doing Homework【状态压缩DP】
    POJ 1077 Eight【八数码问题】
    状态压缩 POJ 1185 炮兵阵地【状态压缩DP】
    POJ 1806 Manhattan 2025
    POJ 3667 Hotel【经典的线段树】
    状态压缩 POJ 3254 Corn Fields【dp 状态压缩】
    ZOJ 3468 Dice War【PD求概率】
    POJ 2479 Maximum sum【求两个不重叠的连续子串的最大和】
    POJ 3735 Training little cats【矩阵的快速求幂】
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309273.html
Copyright © 2011-2022 走看看