Spring预热之Java反射

概述

Java反射机制:在运行状态中,能够知道任意类的所有属性和方法,能够调用任意对象的所有属性和方法

和"反"对应的就是"正",所谓的"正"就是指我们正常new出一个对象进行相应操作。那么如果我们不知道要使用的类是什么怎么办?比如JDBC中加载不同的数据库驱动程序、Spring框架中注入各种Bean,同一个业务要操作很多不同的类,没办法把所有的对象new出来,这时候就要使用反射创建一个实例,然后再操作

常用操作

先写一个类

public class Student {
    @Getter
    @Setter
    private String name;
    @Getter
    @Setter
    private int id;

    public Student() {
        System.out.println("无参构造器");
    }

    private Student(String name) {
        this.name = name;
        System.out.println("name:" + name);
    }

    public Student(String name, int id) {
        this.name = name;
        this.id = id;
        System.out.println("name:" + name + "id" + id);
    }
    private void eat(String name) {
        System.out.println(name + " eat chuanchuan");
    }

    public void study(){
        System.out.println("study");
    }
}

获取Class对象

为什么要获取Class对象呢?因为所有的操作都是要先根据Class对象创建一个实例出来

  1. 使用Class.forName(“类全名”),因为类可能不存在,所以会抛出ClassNotFoundException异常

    Class c1 = Class.forName(“java.lang.String”);
    
  2. 通过类名.Class获取,最安全、性能最高,只适合在编译前就知道要操作的类名的场景

    Class c1 = String.class
    
  3. 通过对象的getClass()获取,适用于传过来一个Object的对象,但是不知道具体是什么类

    String str = new String("Hello");
    Class c3 = str.getClass();
    

创建对象

有两种方法:

  1. 通过Class的newInstance()方法,只能使用无参构造方法

    Class<?> studentClass = Student.class;
    Student student = (Student) studentClass.newInstance();
    
  2. 通过Constructor对象的newInstance()方法,可以选择构造方法,但是不能选择私有构造方法,否则会报NoSuchMethodException异常

    Constructor<?> constructor1 = studentClass.getConstructor();
    Constructor<?> constructor2 = studentClass.getConstructor(String.class);
    Student s1 = (Student) constructor1.newInstance();
    Student s2 = (Student) constructor2.newInstance("zcs");
    

    最后一行代码会报错,因为Student(String name)是私有的,那么如何获取私有的呢?看一下常用API

    方法名作用
    getConstructors()获取public构造方法
    getDeclaredConstructors()获取所有构造方法
    getConstructor(Class<?>…)获取指定参数的public构造方法
    getDeclaredConstructor(Class<?>…)获取指定参数的构造方法(可以是private)

    把Constructor换成Field和Method就是对属性和方法的操作,区别就是返回值不同

    例如Method method=class.getDeclaredMethod()

    还有就是对于获取私有类型的方法(带Declraed的),需要设置setAccessible(true),具体见下文

//        私有构造方法
        Constructor<?> constructor3 = studentClass.getDeclaredConstructor(String.class);
        constructor3.setAccessible(true);
        Student s3 = (Student) constructor3.newInstance("zcs");

//        私有属性
        Field name = studentClass.getDeclaredField("name");
        name.setAccessible(true);
        System.out.println(name.get(s3));

//        私有方法,第一个参数是方法名,第二个是参数类型
        Method method = studentClass.getDeclaredMethod("eat",String.class);
        method.setAccessible(true);
//		 第一个参数是实例,第二个是具体参数
        method.invoke(s3,"zcs");
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值