Java----反射

    什么是反射?        

            反射就是允许对成员变量、成员方法和构造方法的信息进行编程访问。换句话来讲,就是通过反射,我们可以在不需要创建其对象的情况下就可以获取其定义的各种属性值以及方法。常见的应用就是IDEA中的提示功能,当我们使用某个对象,使用“.”的时候,IDEA会自动进行提示,会弹出一个显示关于该对象所有能调用的方法。

     想要使用反射,首先要先创建某个对象的字节码对象,常见的创建方式有以下几种,(第一种的地址可以在IDEA中使用右键复制其引用):

    代码编写

    这里我们采用第一种进行创建:

    package com.wxy.instance;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.util.Arrays;
    
    public class ClassTest {
        public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {
            //获得字节码对象
            Class<?> clazz = Class.forName("com.wxy.instance.Student");
            
            //调用获取构造列表,并选择其中的第3个
            Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
            System.out.println(Arrays.toString(declaredConstructors));
    
            Constructor<?> declaredConstructor = declaredConstructors[2];
            
            //由于我的对象中第3个构造方法是private修饰,不允许外部调用,所以我们需要使用调用下面的方法,临时取消权限的校验
            declaredConstructor.setAccessible(true);
    
            //通过获得的构造方法使用newInstance()可以创建对象
            Student xiaoming = (Student) declaredConstructor.newInstance("xiaoming");
            System.out.println(xiaoming);
        }
    }
    

    以下是示例对象:

    package com.wxy.instance;
    
    public class Student {
        private Integer id;
        private String name;
        private Integer age;
    
    
        public Student() {
        }
    
        private Student(String name) {
            this.name = name;
        }
    
        private Student(Integer id, String name, Integer age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        /**
         * 获取
         * @return id
         */
        public Integer getId() {
            return id;
        }
    
        /**
         * 设置
         * @param id
         */
        public void setId(Integer id) {
            this.id = id;
        }
    
        /**
         * 获取
         * @return name
         */
        public String getName() {
            return name;
        }
    
        /**
         * 设置
         * @param name
         */
        public void setName(String name) {
            this.name = name;
        }
    
        /**
         * 获取
         * @return age
         */
        public Integer getAge() {
            return age;
        }
    
        /**
         * 设置
         * @param age
         */
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String toString() {
            return "Student{id = " + id + ", name = " + name + ", age = " + age + "}";
        }
    
        /**
         * 测试反射获取成员方法
         * @param arg
         */
        private String testMethodGet(String arg){
            System.out.println(this.name + "调用调用成功,传递的参数是"  + arg);
            return "调用成功";
        }
    }
    

    除了获取构造方法,我们还可以使用反射获取其成员变量,包括其记录值、修饰符、数据类型等。

            //在刚刚我们使用反射创建了一个对象
            Student xiaoming = (Student) declaredConstructor.newInstance("xiaoming");
            System.out.println(xiaoming);
    
            //我们使用字节码对象调用其方法获得我们的成员变量name
            Field name = clazz.getDeclaredField("name");
    
            //由于其变量是private修饰,所以我们需要禁用其权限校验
            name.setAccessible(true);
            //通过get方法可以获取其记录值
            String nameByXiaoMing = (String) name.get(xiaoming);
    
            System.out.println(nameByXiaoMing);
            //使用set可以修改其记录值
            name.set(xiaoming,"xiaohong");
    
            System.out.println(name.get(xiaoming));

    结果如下:

    同样我们还可以获得其内部方法:

    
            //获取方法
            Method testMethodGet = clazz.getDeclaredMethod("testMethodGet", String.class);
            //由于该方法时private
            testMethodGet.setAccessible(true);
            //需要传入调用的对象以及调用所需的参数,如果是空参可省略,有返回值则可以进行接收
            String result = (String) testMethodGet.invoke(xiaoming, "塔斯汀");
    
            System.out.println(result);

     结果如下:

    总结

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值
    程序员都在用的中文IT技术交流社区

    程序员都在用的中文IT技术交流社区

    专业的中文 IT 技术社区,与千万技术人共成长

    专业的中文 IT 技术社区,与千万技术人共成长

    关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

    关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

    客服 返回顶部