• 使用反射机制实现反编译


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

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

  • 相关阅读:
    Smali语法
    css 实现垂直水平居中常用方法
    css border实现三角形
    vue-router学习笔记
    vuex状态管理
    es6 reduce的用法
    vue学习笔记
    chrome调式工具
    前端需要了解的http知识
    underscore.js and moment.js
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309273.html
Copyright © 2020-2023  润新知