反射

作者: 超级笔记本 | 来源:发表于2019-09-30 13:32 被阅读0次

    1、获取类类型 Class

    三种方法获取类类型

    //1 静态变量class
    Class class1 = User.class;
    System.out.println(class1.getName());
    //1 类对象的getClass方法
    User user = new User();
    Class c2 = user.getClass();
    System.out.println(c2.getName());
    //3 Class静态方法forName
    Class class3 = Class.forName("com.my.java.User");;
    System.out.println(class3.getName());
    

    输出结果

    com.my.java.User
    com.my.java.User
    com.my.java.User
    

    1、成员变量 Field

    1、getDeclaredField获取私有成员变量,需要setAccessible(true),否则报错IllegalAccessException
    2、getField只能获取public的变量,如果知道私有变量,则报错NoSuchFieldException

     Field field1 = c2.getField("msg1");
    Object msg1 = field1.get(o);
    System.out.println("成员变量msg1:" + msg1);
    Field field2 = c2.getDeclaredField("msg2");
    field2.setAccessible(true);
    Object msg2 = field2.get(o);
    System.out.println("成员变量msg1:" + msg2);
    

    获取所有的成员变量

            //所有的public成员变量,包括父类
            Field[] fields = c2.getFields();
            for (Field field : fields) {
                System.out.println(field.getName());
            }
            //所有的方法,不包括父类
            Field[] declaredFields = c2.getDeclaredFields();
            for (Field field : declaredFields) {
                System.out.println(field.getName());
            }
    

    方法对应能力范围


    20170727235210926.png

    2、方法 Method

    1、getDeclaredMethod调用私有方法时,需要添加setAccessible(true)方法,否则报错IllegalAccessException
    2、invoke执行该方法,并传递参数类型,不传或传错类型报错IllegalAccessException
    3、getMethod或者getDeclaredMethod传递多个参数类型时可以new Class[]{String.class, String.class}

    Class class1 = User.class;
    Object o = class1.newInstance();//获取对象
    //获取所有public方法,包括父类,参数:方法名,方法参数类的类类型
    Method fun1 = c2.getMethod("fun1", String.class, String.class);
    fun1.invoke(o, "admin", "123456");
    //获取所有的方法,不包括父类,参数:方法名,方法参数类的类类型
    Method fun2 = c2.getDeclaredMethod("fun2", String.class);
    fun2.setAccessible(true);
    fun2.invoke(o,"输出一段内容");
    

    获取所有的方法

    //所有的public方法,包括父类
    Method[] methods = c2.getMethods();
    for (Method method : methods) {
        System.out.println(method.getName());
    }
    //所有的方法,不包括父类
    Method[] declaredMethods = c2.getDeclaredMethods();
    for (Method method : declaredMethods) {
         System.out.println(method.getName());
    }
    

    方法对应能力范围


    20170727235237680.png

    3、构造方法 Constructor

    同 Field 和 Method 一样,同样存在

    getConstructor()
    getDeclaredConstructor()
    getConstructors()
    getDeclaredConstructor()
    

    方法对应能力范围


    20170727235303590.png

    4、通过反射了解集合泛型的本质

    这个学到了,第一次知道这个。Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译到了运行期就无效了。

            List<String> list = new ArrayList<>();
            list.add("一个String元素");
            Class c = list.getClass();
            Method method = c.getMethod("add", Object.class);
            method.invoke(list, 20);
            System.out.println("list.size:" + list.size());
    

    参考文章
    反射进阶,编写反射代码值得注意的诸多细节
    Java基础与提高干货系列——Java反射机制

    相关文章

      网友评论

          本文标题:反射

          本文链接:https://www.haomeiwen.com/subject/ucyquctx.html