> 文档中心 > java反射使用

java反射使用


反射的概念:

在程序运行期间,动态获取和调用类的成员或者成员方法的机制,反射可以无视修饰符访问权限检查(调用的时候使用setAccessible(true)取消访问检查)。

反射核心类:

  1. java.lang.class类:这个类是java的类的字节码文件对象类,每一个类都会有一个对应的class对象。有三种方式可以获取到一个类的Class对象
    1. 类.class,比如:Student.class
    2. 使用类的实例对象调用getClass方法。getClass方法是定义在Object中的
    3. Class.forName("类的全路径:报名+类名")
  2. Constructor构造函数对象类,使用该类的实例调用newInstance()方法,即可通过该构造函数对象创建一个对应的类的实例对象,可以通过类的Class对象来获取类的构造函数,主要的获取函数有几个:
    Class clazz = Student.class;Constructor constructor = clazz.getDeclaredConstructor();constructor.setAccessible(true);    //私有构造方法需要取消访问检查Student student1 = constructor.newInstance();
    1. getConstructors():返回所有的公共构造函数对象数组,不需要参数
    2. getDeclaredConstructors():返回所有的(包括不是public修饰的)构造函数对象数组,不需要参数
    3. getDeclaredConstructor(),返回一个构造函数对象(可以是非public的),参数需要跟实际的构造函数的参数类型对应(使用构造函数参数的class对象),如果没有就不需要
    4. getConstructor():与3的区别是只能获取公共的构造函数
  3. Field,类的成员变量对象,使用该对象的get或set方法可以动态访问类的成员变量(私有的需要取消访问检查,需要传入对应的类的实例对象),使用class对象获取该对象的方法:
    Constructor constructor = clazz.getConstructor();Student student2 = constructor.newInstance();// clazz.getField("age");// Field[] declaredFields = clazz.getDeclaredFields();// Field[] fields = clazz.getFields();Field age = clazz.getDeclaredField("age");age.setAccessible(true);age.setInt(student2,58);age.get(student2);
    1. getFields():返回全部公共成员变量对象数组,不需参数
    2. getDeclaredFields():返回全部(包括非公共)的成员变量对象数组,不需要参数
    3. getField("age"),返回指定的公共的成员变量对象,参数是需要获取的字段名
    4. getDeclaredField("age"):返回指定的成员变量对象,可以是私有的
  4. methods成员方法对象,使用该对象的invoke方法可以动态调用方法对象所代码的方法(需要传入类的实例),使用class对象获取methods的四种方法:
    1. getMethods(),获取所有的公共成员方法对象数组
    2. getDeclaredMethods():获取所有的包括非公共的成员方法的方法对象数组
    3. getMethod:获取指定的公共方法对象,参数是方法名
    4. getDeclaredMethod():可以获取私有的方法的方法对象,参数是方法名
 Class clazz = Student.class; Constructor constructor = clazz.getConstructor(); Student student2 = constructor.newInstance();// Method[] methods = clazz.getMethods();// clazz.getDeclaredMethods();Method method = clazz.getMethod("study");//method.setAccessible(true);    私有方法需要method.invoke(student2);// clazz.getDeclaredMethod();

反射的优缺点:

        有点:反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类;

        缺点:1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。      
       2、使用反射会模糊程序内内部逻辑:程序员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。   至于执行效率的话,还可以,因为它是一种强类型语言,执行效率不错。不过,建议将反射过后,保存进 cache中。

        3、破坏程序的封装性,会带来安全问题