• 反射的应用


    反射概述

    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());
            }
    学习中,博客都是自己学习用的笔记,持续更新改正。。。
  • 相关阅读:
    【WP8】关于类库本地化问题
    【WP8】富文本功能实现
    【WP8】换肤功能的实现
    【WP8】图片缓存控件
    【WP8】图片压缩处理
    【WP8】让TextBox文本支持滑动(Scroll)
    <正则吃饺子> :关于Guava中 Joiner 和 Splitter 的简单使用
    <正则吃饺子> :关于前端往后端传递布尔值参数的问题
    <正则吃饺子>:关于使用powerDesign连接oracle数据库,导出数据表结构(ER图吧)
    <正则吃饺子>:关于集合的简单整理总结
  • 原文地址:https://www.cnblogs.com/Tunan-Ki/p/11681226.html
Copyright © 2020-2023  润新知