反射技术

多用于框架和组件,写出复用性高的通用程序。
1. class类
获得class类的三种方法
(1)已知类–类名.class
(2)已知对象–对象.getClass()
(3)完整类名 String格式–Class.forName(完整类名) 常用

public void demo1() throws ClassNotFoundException {
        // 获得class对象的三种方式
        // 1.已知类
        Class c1 = ReflectTest.class;
        // 2.已知对象
        Object o = new ReflectTest();
        Class c2 = o.getClass();
        // 3.完整的类名String格式
        String className = "Reflect.qddx.ReflectTest";
        Class c3 = Class.forName(className);
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
    }
  1. Constructor
    通过字节码对象获得构造器 ,成员变量方法,有两种
    (1)获得所有getConstructors()
    (2)获得指定getConstructor()
    通过 newInstance()获得对象
public void demo2() throws Exception {
        // 获得 Person的字节码对象
        String className = "Reflect.qddx.Person";
        Class c = Class.forName(className);// c 就是 Person的字节码对象

        // 通过字节码获得一个类的构造器
        Constructor[] constructors = c.getConstructors();
        System.out.println(constructors.length);
        // 获得指定构造器
        Constructor constructor1 = c.getConstructor();
        // 获得String类型参数的构造器
        Constructor constructor2 = c.getConstructor(String.class);

        Person p1 = new Person();// 调用无参构造器
        // 使用反射实现相同的效果
        Object p2 = constructor1.newInstance();// 调用无参构造器 构造Person对象
        Object p2_2 = c.newInstance();// 通过class对象newInstance调用目标类无参构造器
        Person p3 = new Person("abcd");// 调用有参的构造器
        // 使用反射调用String 参数构造器
        Object p4 = constructor2.newInstance("abcd");// 与p3 等价

    }

3.Field类
field对象的获得
(1)getFields()获得所有public 成员变量,包括父类继承。
(2)getDeclaredFields() 获得当前类定义所有成员–包括private
当需要获得指定成员时,上面的方法 传入参数即可。
操作private属性,将setAccessible(true)

public void demo3() throws Exception {
        Person p = new Person("Linda");
        // 获得Person的字节码对象
        Class c = Class.forName("Reflect.qddx.Person");
        // 操作成员变量实例 name 获得name代表field对象
        Field[] f1 = c.getFields();
        System.out.println(f1.length);

        Field[] f2 = c.getDeclaredFields();
        System.out.println(f2.length);

        // 获得name 成员变量
        Field field = c.getDeclaredField("name");
        field.setAccessible(true);// 设置可以访问私有的成员变量
        // 获得p对象指定的name值
        Object value = field.get(p);// 等价于p.getName()
        System.out.println(value);

        // 修改p的值
        field.set(p, "MerLin");
        System.out.println(field.get(p));

    }
  1. Method
    getDeclaredMethods()获得所有当前类声明方法。
    getDeclareMethod()获得指定方法。
    通过Method类提供invoke()执行方法
public void demo4() throws Exception {
        Person p = new Person();
        // 调用 p 对象中setName 设置 name的值 mary
        // 获得Person的字节码对象
        Class c = Class.forName("Reflect.qddx.Person");
        // 2.操作setName 获得setName 对应反射对象 Method对象
        // String类型参数 setName方法
        Method setName = c.getDeclaredMethod("setName", String.class);
        // 调用p对象的setName
        setName.invoke(p, "Melin");// p.setName("Merlin")
        // 读取name值得getName方法
        Method getName = c.getDeclaredMethod("getName");
        Object name = getName.invoke(p);
        System.out.println(name);
    }

综合应用实例

public void demo5() throws Exception {
        // 已知String完整类型名 获得字节码对象
        String className = "Reflect.qddx.Person";
        Class c = Class.forName(className);
        // 已知class对象 构造实例
        Object obj = c.newInstance();
        // 获得字节码对象中指定的属性和方法
        Field f = c.getDeclaredField("name");// 获得name属性
        Method setName = c.getDeclaredMethod("setName", String.class);// 获得setName方法。
        // 修改属性的值,执行相应的方法
        f.setAccessible(true);
        f.set(obj, "Mary");

        setName.invoke(obj, "Linda");
        // 以上代码等价于以下代码
        Person p = new Person();
        // p.name = "Mary";
        p.setName("Linda");

    }

案例 :晚会
工厂+反射+配置文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值