9.反射的基本原理

1.反射的原理

  * 应用在一些通用性比较高的代码中

  * 例如后面学到的框架,大多数都是使用反射来实现的

  * 在框架开发中,都是基于配置文件开发

    在配置文件中配置了类,可以通过反射得到类中的所有内容,可以让类中的某些方法来执行

  * 类中的所有内容:属性、没有参数的构造方法、有参数的构造方法、普通方法

  * 画图分析反射的原理

      * 首先需要把java文件保存到本地硬盘上 .java

      * 编译java文件,成.class文件

      * 万事万物都是对象,class文件在内存中使用class类表示

      * 当使用反射时候,首先需要获取到class类,得到这个类之后,就可以得到class文件中的所有内容

      * 属性通过一个类 Field 表示

      * 构造方法通过一个类 Constructor 表示

      * 普通方法通过一个类 Method类 表示

 

2.实例

Persion类

package Day5;

public class Persion {
    //属性
    private String id;
    private String name;
    
    //没有参数的构造方法
    public Persion() {}
    
    //有参数的构造方法
    public Persion(String id , String name) {
        this.id = id;
        this.name = name;
    }
    
    //普通方法
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 

 

  (1)获取class类的三种方式

public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class c1 = Persion.class;
        Class c2 = new Persion().getClass();
        //注意参数为包名+类名,推荐使用这种方式
        Class c3 = Class.forName("Day5.Persion");
    }
}

  (2)操作无参数的构造方法

  @Test
    public void test1() throws Exception   {
        //获取calss类
        Class c3 = Class.forName("Day5.Persion");
        //获取persion类的实例(当创建persion实例的时候,无参数的构造方法已经运行了)
        Persion persion = (Persion) c3.newInstance();
        //通过persion实例调用里面的普通的方法
        persion.setName("张三");
        //我们来查看我们设置的值是否成功
        System.out.println(persion.getName());
    }

 

  (3)操作有参数的构造方法

  @Test
    public void test2() throws Exception {
        //获取class类
        Class c3 = Class.forName("Day5.Persion");
        //获取有参数的构造方法(c3.getConstructors();  获取所有的构造方法)
        //里面的参数是使用class形式传递的(persion有参的构造方法是String类型)
        //java.lang.reflect.Constructor
        Constructor cs =  c3.getConstructor(String.class,String.class);
        //通过有参数的构造方法获取persion实例
        Persion persion = (Persion) cs.newInstance("101","张三");
        //输出我们设置的值
        System.out.println(persion.getId()+" "+persion.getName());
    }

 

  (4)操作属性

@Test
    public void test3() throws Exception {
        //获取class类
        Class c3 = Class.forName("Day5.Persion");
        //获取persion的实例
        Persion persion = (Persion) c3.newInstance();
        //获取name属性
        Field field = c3.getDeclaredField("name");
        //因为我们定义的属性是私有的,所以不能直接操作,我们设置为可以操作私有属性
        field.setAccessible(true);
        //设置name的值为张三
        field.set(persion, "张三");
        //输出name属性的值
        System.out.println(field.get(persion));
    }

  (5)操作普通方法(如果方法为私用的。需要设置method.setAccessible(true))

    注意:当使用反射操作静态的方法的时候invokie方法的第一个参数里面写一个null

@Test
    public void test4() throws Exception {
        //获取class类
        Class c3 = Class.forName("Day5.Persion");
        //获取persion的实例
        Persion persion = (Persion) c3.newInstance();
        //获取setName普通方法(参数一:方法名     参数二:方法里面的参数类型)
        Method method = c3.getDeclaredMethod("setName", String.class);
        //通过获取的setName设置值
        method.invoke(persion, "张三");
        //输出
        System.out.println(persion.getName());
    }

 

posted @ 2018-06-24 17:56  江小白鞋  阅读(399)  评论(0编辑  收藏  举报