反射

时间:2019-08-17
本文章向大家介绍反射,主要包括反射使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

为什么需要反射?

需求:我公司定义了一组接口,然后第三方公司按照我公司的接口实现了一套功能,然后交给我们,但是我们公司的项目已经结束,如何实现动态加载第三方公司提供的功能。(类似于热拔插效果)

什么是反射?

反射就是八类中的各种成分映射成各种对象。等同于解刨,可以拿到类中任何成分。

反射常用类:

  • Class:获取类和类的成员信息
  • Filed:可访问的类的属性
  • Method:类的方法
  • Constructor:类的构造方法

使用反射基本步骤:

  • 1.导入java.lang.reflect.*
  • 2.获得需要操作的类的Java.lang.Class对象
  • 3.调用Class的方法获取Field、Method等对象
  • 4.使用反射API进行操作(设置属性﹑调用方法)

获取类对象的方法:

  • 通过对象----person.getClass();
  • 通过类名----Person.class;
  • 通过Class.forName("xxxx");------Class.forName("xxxxxx");

获取类的类对象后可以获取类中的属性、构造方法、非构造方法

现获取类对象  :   Class<?>  clazz = Class.forName("xxxx.xxx.xxPerson");

【0】动态创建对象

方法一:使用Class的newInstance()方法,仅适用于无参构造方法

        Class clazz=Class.forName("com.qf.reflection.Student");
        Object obj=clazz.newInstance();   

方法二:调用Constructor的newInstance()方法,适用所有构造方法

        Constructor cons = clazz.getConstructor(new Class[]{ String.class,  int.class, float.class });
        Object obj = cons.newInstance(new Object[ ] {"lkl", 32, 56.5f });

【1】获取属性可以获取全部属性,也可以获取单个属性

  1.获取全部属性用的类是Field[] ,   ----------     Field[] declaredFields = clazz.getDeclaredFields();

  2.获取单个属性用的类是Field,     -----------     Field name = clazz.getDeclaredField("name");

   注:Declared这个关键字获取私有的必须要带上,如果想修改private属性,必须先修改权限可以访问    如:name.setAccessible(true);

  

 public static void getField() throws  Exception{
        //1获取类对象
        Class<?> clazz = Class.forName("com.qf.Person");
        //2获取
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        //获取单个
        System.out.println("--------------------------");
        Field name = clazz.getDeclaredField("name");
//
//        Person wangwu=new Person();
//        wangwu.name="王五";
        Object wangwu = clazz.newInstance();

        //赋值
        name.setAccessible(true);
        name.set(wangwu, "王五");//  wangwu.name="王五";

        //获取
        Object object=name.get(wangwu);// wangwu.name
        System.out.println(object);


    }

   【2】 反射出构造方法

第一步仍然是现获取类对象

1.获取所有的构造方法(不包括私有化的构造方法

         Constructor<?>[] constructors = clazz.getConstructors();

2.获取单个构造方法(无参)

         Constructor<?> constructor = clazz.getConstructor();

2.获取单个构造方法(有参)

         Constructor<?> constructor1 = clazz.getConstructor(String.class, int.class, String.class);

注:利用有参和无参的构造方法可以创建对象

  1(无参)Object lisi = clazz.getConstructor().newInstance();

  2(有参)clazz.getConstructor(String.class, int.class, String.class).newInstance("王五", 20, "");

public static void getConstructor() throws Exception{
        Class<?> clazz=Class.forName("com.qf.Person");
        //1获取构造方法
        Constructor<?>[] constructors = clazz.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("--------------------------");
        //2获取单个构造方法
        //2.1获取无参构造方法
        Constructor<?> constructor = clazz.getConstructor();
        //2.2获取带参
        Constructor<?> constructor1 = clazz.getConstructor(String.class, int.class, String.class);
        System.out.println(constructor);
        System.out.println(constructor1);
        //3利用构造方法创建对象
        System.out.println("---------利用构造方法创建对象------------");
        Person zhangsan=new Person();
        Object lisi = constructor.newInstance();
        System.out.println(zhangsan);
        System.out.println(lisi);

        Object wangwu = constructor1.newInstance("王五", 20, "男");
        System.out.println(wangwu);

        //简单创建对象的方法
        Object o = clazz.newInstance();
        System.out.println(o.toString());

    }

【获取非构造方法】

仍然是先创建类对象  Class<?> clazz=Class.forName("xxx.xxx.Person");

1.获取所有的公开方法,包括自己和父类的

      Method[] methods = clazz.getMethods();

2.获取公类自己所有的方法,包括非公开的方法

     Method[] methods = clazz.getDeclaredMethods();

3 获取单个方法(无参)

Method show = clazz.getMethod("show");
show.invoke(zhangsan);// zhangsan.show();
注:必须要指定对象 invoke(obj p)
public static void getMethod() throws Exception{
        //1获取无参的方法
        Class<?> clazz=Class.forName("com.qf.Person");
        //Method[] methods = clazz.getMethods();//获取公类自己公开的方法,继承的公开方法
//        Method[] methods = clazz.getDeclaredMethods();//获取公类自己所有的方法,包括非公开的方法
//        System.out.println("-----------getMethods();----------");
//        for (Method method : methods) {
//            System.out.println(method);
//        }

//        Person p=new Person();
//        p.show();

        Object zhangsan = clazz.newInstance();
        
        Method show = clazz.getMethod("show");
        show.invoke(zhangsan);// zhangsan.show();

        //2获取有参
        Method show2=clazz.getMethod("show",String.class);
        show2.invoke(zhangsan, "北京");

        //3获取带返回值的方法
        Method getInfo = clazz.getMethod("getInfo");
        Object value=getInfo.invoke(zhangsan);
        System.out.println(value);

        //4获取静态方法
        Method print = clazz.getMethod("print");
        print.invoke(null);// Person.print();

        //5私有方法
        Method show3 = clazz.getDeclaredMethod("show", String.class, String.class);
        //设置访问权限无效
        show3.setAccessible(true);
        show3.invoke(zhangsan, "上海","zhangsan@qq.com");
    }

注:Java ,内省机制,是一种使用反射获取或设置对象属性的一种方式

  • Introspector 内省类
  • BeanInfo 类的信息
  • PropertyDescriptor 属性描述符
 
public class Demo {
    public static void main(String[] args) throws Exception{
        CarManager carManager=new CarManager();
        //car
        Field car = CarManager.class.getDeclaredField("car");
        Class<?> carClass = car.getType();

        //获取注解
        CarAnnotation annotation = car.getAnnotation(CarAnnotation.class);
        Object o = carClass.newInstance();

        //Java ,内省机制,是一种使用反射获取或设置对象属性的一种方式
        // Introspector  内省类
        // BeanInfo 类的信息
        // PropertyDescriptor 属性描述符
        Class<?> clazz3=CarAnnotation.class;
        //1使用内省类Introspector获取类信息对象
        BeanInfo beanInfo = Introspector.getBeanInfo(carClass);
        //2调用类信息的getPropertyDescriptors()获取属性描述符
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        //3遍历
        for (PropertyDescriptor pd : propertyDescriptors) {
            //System.out.println(pd.getName());
            //System.out.println(pd.getName());
            String name=pd.getName();//属性
            try {
                Method method = clazz3.getMethod(name);
                if(method!=null){
                    Object value = method.invoke(annotation);
                    Method writeMethod = pd.getWriteMethod();
                    writeMethod.invoke(o,value);
                }
            } catch (Exception e) {
                continue;
            }
        }


        System.out.println(o.toString());

    }
}



 

     

原文地址:https://www.cnblogs.com/lcj12121/p/11367409.html