zoukankan      html  css  js  c++  java
  • java反射机制的原理与简单使用

    一、 原理

        简单的来说,反射机制其实就是指程序在运行的时候能够获取自身的信息。如果知道一个类的名称/或者它的一个实例对象, 就能把这个类的所有方法和变量的信息(方法名,变量名,方法,修饰符,类型,方法参数等等所有信息)找出来。如果明确知道这个类里的某个方法名+参数个数 类型,还能通过传递参数来运行那个类里的那个方法,这就是反射。

        尽管Java不是一种动态语言,但它却有一个非常突出的动态机制:Reflection。它使我们可以于运行时加载、探知、使用编译期间完全未知的 classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、 或对其fields设值、或唤起其methods。既一种“看透class”的能力。

        当然,在平时的编程中,反射基本用不到,但是在编写框架的时候,反射用的就多了,比如你要使用某一个类进行操作,但是这个类是用户通过配置文件配置进来 的,你需要先读配置文件,然后拿到这个类的全类名:比如test.Person,然后在利用反射API来完成相应的操作。

    二、 优缺点

        反射的优点当然是体现在它的动态性上面,能运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,降低类之间的藕合性。 一句话,反射机制的优点就是可以实现动态创建对象和编译,特别是在J2EE的开发中,它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把 它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定 是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建 和编译,就可以实现该功能。 
        它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。

    三、 使用反射实现类文件的反编译

    package other;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import test.Person;  //引入测试类文件
    
    public class ReflectionTest {
        public static void main(String[] args) {
            Class c = null;
            try {
                // 根据传入的类的全名来创建Class对象,注意必须是全名
                c = Class.forName("test.Person");
                // 得到包路径
                System.out.println("package " + c.getPackage().getName() + ";
    ");
                // 得到类修饰符
                System.out.print(Modifier.toString(c.getModifiers()));
                //得到类名
                System.out.print(" class " + c.getSimpleName());
                //得到父类名
                System.out.print(" extends " + c.getSuperclass().getSimpleName());
                //得到类实现的接口数组
                Class[] inters = c.getInterfaces();
                if (inters.length > 0) {
                    System.out.print(" implements ");
                    for (int i = 0; i < inters.length; i++) {
                        System.out.print(inters[i].getSimpleName());
                        if (i < inters.length - 1) {
                            System.out.print(", ");
                        }
                    }
                }
                System.out.println(" {");
                // 获取类属性
                printField(c);
                // 获取类构造器
                printConstructor(c);
                // 获取类方法
                printMethods(c);
                System.out.println(" }");
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        
        private static void printConstructor(Class c){
            Constructor[] cs = c.getConstructors();
            for (int i = 0; i < cs.length; i++) {
                System.out.println();
                System.out.print("	");
                // 得到整数形式构造函数修饰符,使用Modifier进行解码
                System.out.print(Modifier.toString(cs[i].getModifiers()) + " ");
                // 得到方法名
                System.out.print(cs[i].getName() + "(");
                // 得到方法参数数组
                Class[] paras = cs[i].getParameterTypes();
                for (int j = 0; j < paras.length; j++) {
                    System.out.print(paras[j].getSimpleName() + " arg" + j);
                    if (j < paras.length - 1) {
                        System.out.print(", ");
                    }
                }
                System.out.print(")");
                System.out.println(" {");
                System.out.println("		\\方法体");
                System.out.println("	}");
            }
        }
    
        private static void printField(Class c) {
            // 得到属性数组
            Field[] fs = c.getDeclaredFields();
            for (int i = 0; i < fs.length; i++) {
                System.out.print("	");
                // 得到整数形式属性修饰符,使用Modifier进行解码
                System.out.print(Modifier.toString(fs[i].getModifiers()) + " ");
                // 得到属性类型
                System.out.print(fs[i].getType().getSimpleName() + " ");
                // 得到属性名
                System.out.println(fs[i].getName() + ";");
            }
        }
    
        public static void printMethods(Class c) {
            // 得到方法数组
            Method[] md = c.getMethods();
            for (int i = 0; i < md.length; i++) {
                System.out.println();
                System.out.print("	");
                // 得到整数形式方法修饰符,使用Modifier进行解码
                System.out.print(Modifier.toString(md[i].getModifiers()) + " ");
                // 得到方法返回类型
                System.out.print(md[i].getGenericReturnType() + " ");
                // 得到方法名
                System.out.print(md[i].getName() + "(");
                // 得到方法参数数组
                Class[] paras = md[i].getParameterTypes();
                for (int j = 0; j < paras.length; j++) {
                    System.out.print(paras[j].getSimpleName() + " arg" + j);
                    if (j < paras.length - 1) {
                        System.out.print(", ");
                    }
                }
                System.out.print(")");
                // 得到抛出的异常类数组
                Class[] exceps = md[i].getExceptionTypes();
                if (exceps.length > 0) {
                    System.out.print(" throws ");
                    for (int k = 0; k < exceps.length; k++) {
                        System.out.print(exceps[k].getSimpleName());
                        if (k < exceps.length - 1) {
                            System.out.print(", ");
                        }
                    }
                }
                System.out.println(" {");
                System.out.println("		\\方法体");
                System.out.println("	}");
            }
        }
    }

    文章来源:guntong

    作者:guntong

  • 相关阅读:
    web服务器-Apache
    nginx优化
    nginx下载限速
    nginx-URL重写
    HDU 5358 First One 求和(序列求和,优化)
    HDU 5360 Hiking 登山 (优先队列,排序)
    HDU 5353 Average 糖果分配(模拟,图)
    UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。
    HDU 5348 MZL's endless loop 给边定向(欧拉回路,最大流)
    HDU 5344 MZL's xor (水题)
  • 原文地址:https://www.cnblogs.com/a1111/p/12816430.html
Copyright © 2011-2022 走看看