• 认识和总结反射


    1.问题的提出:

    (1)给你一个类的全路径,比如

    classPath="com.cx.Cat"

      可以根据classPath去创建实例,不能直接使用new..

    (2)给一个xml配置文件,如何创建类的一个实例对象

    2.反射用在什么地方?

      主要是用在框架上(struts/hibernate/spring...),如果只写普通的java程序,可以不去考虑反射。反射是java的基石。

    3.(1)每个类被加载后,系统都会为该类生成一个对应的class对象,通过该class对象就可以访问到JVM中的这个类。

     (2)获得Class对象的三种方式:

        //得到Cat的Class对象(得到的是同一个对象)
        //1.通过forName
        Class clazz1=Class.forName("com.cx.reflection.Cat");
        //2.通过class属性
        Class clazz2=Cat.class;
        //3.通过Cat实例对象来获取
        Cat cat=new Cat();
        Class clazz3=cat.getClass();                            

    (3)一旦获取了某个类的Class对象,程序就可以调用Class对象的方法来获得该对象和该类的真实信息了

    4.通过反射生成对象有两种方式:

    (1)使用Class对象的newInstance()方法,要求该Class对象的对应类有默认的构造器,java9中已废除

            Class clazz1=Class.forName("com.cx.reflection.Cat");
            //1.通过Class对象可以创建对象实例
            Cat cat1=(Cat)clazz1.newInstance();
            cat1.show();

    (2)可以指定某个构造函数去创建对象

            //通过(public Cat(String name,int age))来创建实例
            Constructor c1=clazz1.getConstructor(String.class,int.class);
            Cat cat1=(Cat)c1.newInstance("小白",6);
            cat1.show();

    一个容易错的例子:当构造函数的参数是数组的时候

            //通过public Cat(String [] foods)来创建实例
            Constructor c2=clazz1.getConstructor(String[].class);
            String[] foods={"鱼","老鼠"};
            c2.newInstance(foods);

    问题:wrong number of arguments。

    newInstance是可变参数,当传入数组时,会自动的转为c2.newInstance(foods[0],foods[1]),和构造器的形式不匹配,反射不会成功。

    解决办法:将对象数组强转为一个对象

            c2.newInstance((Object)foods);

    5.使用反射调用方法

            //使用反射来调用public void show()
            //cat1.show();
            Method method=clazz1.getMethod("show",null);
            //invoke的第一个参数表示对象实例,第二个参数表示给该方法传入的值
            method.invoke(cat1, null);

    问题:如何去调用一个private的方法?(暴力访问)

            //如何调用私有的函数,比如private void show(String name)
            Method method4=clazz1.getDeclaredMethod("show", String.class);
            //暴力访问
            method4.setAccessible(true);
            method4.invoke(cat1, "小白");

    静态方法:可以method.invoke(null, "小白");

    6.使用反射访问属性值(也分为public和private)

            //使用反射访问属性值
            //Field field=clazz1.getField("name");
            Field field=clazz1.getDeclaredField("name");
            field.setAccessible(true);
            System.out.println(field.get(cat1));
  • 相关阅读:
    云开发数据库 Firebase Firestore 零基础入门视频实战教程(7 个视频)
    在 2021 年你需要掌握的 7 种关于 JavaScript 的数组方法
    2021 年写 JavaScript 代码的 17 个优化技巧
    Redis 学习笔记系列文章之 Redis 的安装与配置 (一)
    selenium webdriver 删除元素
    FFT板子
    pytest一:运行几个简单的测试用例终端显示的信息
    JS 日期取年月日
    将博客搬至CSDN
    c语言编译器
  • 原文地址:https://www.cnblogs.com/sunnyCx/p/7788645.html
Copyright © 2020-2023  润新知