Java反射机制

目录

▐ 反射机制

▐ 获得类的Class对象

▐ 获取类的构造方法

▐ 获取类的属性

▐ 获取成员方法


海漫浩浩,我亦苦作舟!大家一起学习,一起进步!     本人微信:g2279605572(欢迎大家与我交流)

▐ 反射机制

 •  在运行状态中,在仅知道一个类名时,就可以动态获得类中信息,创建对象,调用对象成员的机制称为Java反射机制 

 •  一旦一个类被加载到内存中,都会为该类创建一个Class类的对象(运行时表现)

▐ 获得类的Class对象

获得类的Class对象有三种方式:

  1. 类路径获取:

        Class useClass1 = Class.forName("javareflect.User");

  2. 类名获取:

        Class userClass2 = User.class;

  3. 对象获取:

        User user = new User();
        Class userClass3 =  user.getClass();

获取类的构造方法

1. 获取类的Class对象:

        //1.通过类名,获得到类的Class对象
        Class useClass1 = Class.forName("javareflect.User");

2. 通过类的Class对象来创建对象:

        //2.通过类的Class对象,创建对象
        Object object = useClass1.newInstance();

3. 获得类中的构造方法  (还可以通过构造方法API中的方法创建对象)

        //3.获得类中的构造方法(只能获得指定的公共构造方法)
        //获得无参构造方法
        Constructor constructor1 = useClass1.getConstructor();
        //获得无参构造方法
        Constructor constructor2 = useClass1.getConstructor(String.class,String.class);

        //4.还可以通过构造方法API中的方法创建对象
        Object object1 = constructor1.newInstance();
        Object object2 = constructor2.newInstance("123", "456");

4. 获得类中所有的构造方法,包含私有的:

//只能返回一个特定的构造方法
useClass1.getDeclaredConstructor();
//返回一个包含该类所有声明的构造方法(包括私有、受保护、默认访问和公有构造方法)的数组。
useClass1.getDeclaredConstructors();
//通常不建议操作私有成员

▐ 获取类的属性

1. 获取公共属性:

        //1.通过类型,获得到类的Class对象
        Class useClass = Class.forName("javareflect.User");
        //2.通过类的Class对象,创建对象
        Object object = useClass.newInstance();
        //3.获得类中的成员变量
        Field accountFiled = useClass.getField("account");//获得指定名称的公共的成员变量

2. 获取私有属性:

getDeclaredField( )和getDeclaredFields( )获取私有属性

        //获得指定名称的成员变量,包含私有的
        Field accountFiled = useClass.getDeclaredField("account");

模拟MyBatis反射:

        Class useClass = Class.forName("javareflect.User");
        Object object = useClass.newInstance();

        //模拟mybatis反射
        Map<String,Object> map = new HashMap<>();
        map.put("account","666");
        map.put("password","666");

        //获取所有属性,包括私有
        Field[] declaredFields = useClass.getDeclaredFields();

        for(Field field:declaredFields){
            field.setAccessible(true);
            field.set(object,map.get(field.getName()));
        }
        System.out.println(object);

获取成员方法

1. 获取类中的公共成员方法:

        //1.通过类型,获得到类的Class对象
        Class useClass = Class.forName("javareflect.User");
        //2.通过类的Class对象,创建对象
        Object object = useClass.newInstance();
        //3.获得类中成员方法
        Method work = useClass.getMethod("work");//无参
        //调用访问
        work.invoke(object);

2. 获取当前类声明的所有方法(包括私有方法)

   Class clazz = MyClass.class;
   Method[] methods = clazz.getDeclaredMethods();
   for (Method method : methods) {
       System.out.println("方法名:" + method.getName());
   }

3. 调用获取到的方法 

可以使用invoke()方法来调用获取到的方法。需要注意的是,如果方法是私有方法,需要先设置可访问性:

Class clazz = MyClass.class;
Object obj = clazz.newInstance();
try {
    Method method = clazz.getDeclaredMethod("privateMethod", int.class);
    method.setAccessible(true);
    method.invoke(obj, 10);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
    e.printStackTrace();
}

在上述代码中,privateMethod是一个私有方法,接收一个int类型的参数。通过反射机制获取该方法,并设置可访问性后进行调用。 

模拟MyBatis将拿到的数据封装到对象中:

    /*
    * 模拟MyBatis将拿到的数据封装到对象中
    * */
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //1.通过类型,获得到类的Class对象
        Class useClass = Class.forName("javareflect.User");
        //2.通过类的Class对象,创建对象
        Object object = useClass.newInstance();

        //通过get和set方法对类中的属性进行赋值操作
        Map<String,Object> map = new HashMap<>();
        map.put("account","666");
        map.put("password","666");

        Field[] declaredFields = useClass.getDeclaredFields();
        for (Field field:declaredFields){
            //根据属性名生成set方法名称
            String setmethod = "set"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
            System.out.println(setmethod);
            //通过Class对象,获得对应的Set方法对象
            Method methodObj = useClass.getMethod(setmethod, field.getType());
            methodObj.invoke(object, map.get(field.getName()));
        }
        System.out.println(object);//User{account='666', password='666'}
    }

反射使用的场景:

  • 编程开发工具的代码提示,如 IDEA 或 Eclipse 等,在写代码时会有代码(属性或方法名)提示,这就是通过反射实现的。
  • 很多知名的框架如 Spring,为了让程序更简洁、更优雅,以及功能更丰富,也会使用到反射,比如 Spring 中的依赖注入就是通过反射实现的。
  • 数据库连接框架也会使用反射来实现调用不同类型的数据库(驱动)
  • 动态代理也使用了反射机制。



本次的分享就到此为止了,希望我的分享能给您带来帮助,创作不易也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见 

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值