zoukankan      html  css  js  c++  java
  • 反射的应用

    反射概述

    1. 反射(reflection)的概念是由Smith于1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。通俗的讲就是反射可以在运行时根据执行的类名获得类的信息
    2. Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
    3. 想要解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象。
    4. 反射是框架设计的灵魂(使用前提条件:必须先得到代表的字节码为Class,Class类用于表示.class文件(字节码))

    通过反射获取Class实例的三种方式:

    1. 对象.getClass()
    2. 类名.class
    3. Class.forName("全限定名")

    Class<?> cls = Class.forName("demo1.Student");

      newInstance()  创建此Class对象所表示的类的一个新实例

    Object newInstance = cls.newInstance("老三",18);    

    第三种和前两种的区别:
      1.前两种必须明确类型
      2.第三种是你只要提供这种类型的字符串就行,这种扩展性更强,我不需要知道你的类,我只提供字符串,按照配置文件加载就可以了

    通过反射获取接口和父类

    1. 获取接口 getInterfaces()

    Class<?>[] interfaces = cls.getInterfaces();

    2. 获取父类 getSuperclass()

    Class<?> superclass = cls.getSuperclass();

    通过反射获取运行时类中构造

    1. getConstructor(Class<?>... parameterType) 获取指定公共构造(包括父类)

    Constructor<?> constructor = cls.getConstructor(String.class,int.class,String.class);

    2. getConstructors() 获取本类的公共构造(包括父类)

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

    3. getDeclaredConstructor(Class<?>... parameterTypes) 获取本类指定的构造(共有或私有,但不包括父类)v

    Constructor<?> con2 = cls.getDeclaredConstructor(String.class,int.class);

    4. getDeclaredConstructors() 获取本类所有的构造(共有或私有,但不包括父类)

    Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();

    加Declared和不加Declared区别?
      加Declared可以获取本类所有的(包括私有,但不包括父类)东西,不加Declared获取本类以及父类公有的(不包括私有,但包括父类)东西
    加s和不加s区别?
      加s获取的是多个,返回数组,不加s返回单个

    通过反射获取运行时类中成员变量

    getFields() 获取本类以及父类的所有公共属性(只能获取公有的)

    Field[] fields2 = cls.getFields();
        for (Field field2 : fields2) {
            //获取访问修饰符
            int modifiers2 = field2.getModifiers();
            String string2 = Modifier.toString(modifiers2);
            //获取属性类型
            Class<?> type2 = field2.getType();
            String simpleName2 = type2.getSimpleName();
            //获取属性名称
            String name2 = field2.getName();
            //获取属性值
            Object object2 = field2.get(obj);
            System.out.println(string2+" "+simpleName2+" "+name2+" "+object2);
        }

    getField(String name) 获取本类以及父类中指定的属性(只能获取公有的)

    Field field2 = cls.getField("tName");

    getDeclareFields() 获取本类以及父类的所有属性(包括私有)

        Field[] fields = cls.getDeclaredFields();
        //遍历属性
        for (Field field : fields) {
            field.setAccessible(true);
            //获取访问修饰符
            int modifiers = field.getModifiers();
            String string = Modifier.toString(modifiers);
            //获取属性类型
            Class<?> type = field.getType();
            String simpleName = type.getSimpleName();
            //获取属性名称
            String name = field.getName();
            //获取属性值
            Object value = field.get(obj);
            System.out.println(string+" "+simpleName+" "+name+" "+value);
            
            //设置属性值
            if("name".equals(name)) {
                field.set(obj, "阿莲");
            }else if("age".equals(name)) {
                field.set(obj, 17);
            }else if("love".equals(obj)) {
                field.set(obj, "喜欢老王");
            }
        }

    getDeclareField(String name) 获取本类以及父类的指定属性(包括私有)

    Field field = cls.getDeclaredField("name");

    常用方法:

    set(Object obj,Object value)
      第一个参数:指定对象
      

        if("name".equals(name)) {
            field.set(obj, "阿莲");
        }else if("age".equals(name)) {
            field.set(obj, 17);
        }else if("love".equals(obj)) {
            field.set(obj, "喜欢老王");
        }

    get(Object obj) 返回指定对象上此Field表示的字段值
      参数:指定的对象

    通过反射获取运行时类中成员方法

    getDeclaredMethods() 获取本类所有的成员方法(包括私有)

    Method[] methods = cls.getDeclaredMethods();
        //遍历方法
        for (Method method : methods) {
            //获取访问修饰符
            int modifiers = method.getModifiers();
            String string = Modifier.toString(modifiers);
            //获取返回值类型
            Class<?> type = method.getReturnType();
            String simpleName = type.getSimpleName();
            //获取方法名称
            String name = method.getName();
            //获取参数列表
            Class<?>[] parameterTypes = method.getParameterTypes();
            for (Class<?> class1 : parameterTypes) {
                System.out.println(class1.getSimpleName());
            }
            System.out.println(string+" "+simpleName+" "+name);
            //调用方法
            //有个问题,在循环内部直接调用方法,那么每个方法都会执行,但是我们方法中的参数不一样,所以这个如果需要调用方法需判断
            if("setName".equals(name)) {
                //调用方法
                method.invoke(student, "老王");    //方法的对象,调用的参数
            }
        }
        System.out.println(student);

    getDeclaredMethod(String name,Class<?>... parameterTypes) 获取本类指定的成员方法(包括私有)

    Method method = cls.getDeclaredMethod("toString");

    getMethods() 获取本类以及父类所有的公共成员方法(只能获取公有的)

    Method[] methods2 = cls.getMethods();

    getMethod(String name,Class<?>... parameterTypes) 获取本类以及父类指定的公共方法(只能获取公有的)

    Method method2 = cls.getMethod("show", String.class);

    invoke(Object obj,Object...args) 调用方法
      第一个参数:调用哪个对象的方法
      第二个参数:需要设置的值

        if("setName".equals(name)) {
                    //调用方法
                method.invoke(student, "老王");    //方法的对象,调用的参数
            }

    反射常用的方法

    getName() 获取名称

        String name = method.getName();

    getSimpleName() 获取简称

        Class<?> type = method.getReturnType();
        String simpleName = type.getSimpleName();

    getModifiers() 获取访问修饰符

        int modifiers = method.getModifiers();
        String string = Modifier.toString(modifiers);

    getParameterTypes() 获取参数列表

        Class<?>[] parameterTypes = method.getParameterTypes();
        for (Class<?> class1 : parameterTypes) {
                System.out.println(class1.getSimpleName());
            }
    学习中,博客都是自己学习用的笔记,持续更新改正。。。
  • 相关阅读:
    Intent
    What should we do next in general after collecting relevant data
    NOTE FOR Secure Friend Discovery in Mobile Social Networks
    missing pcap.h
    after building Android Source code
    plot point(one column)
    When talking to someone else, don't infer that is has been talked with others at first. It may bring repulsion to the person who is talking with you.
    进程基本知识
    Python input和raw_input的区别
    强制 code review:reviewboard+svn 的方案
  • 原文地址:https://www.cnblogs.com/Tunan-Ki/p/11681226.html
Copyright © 2011-2022 走看看