Java中的Reflect机制

首先在JAVA中,我们可以分为三个阶段。
1.源代码阶段
源代码也即.java 文件,经过javac编译得到字节码文件.class
而字节码文件经过类加载器(ClassLoader)将其加载到内存中
2.类对象阶段
类对象中就会有之前定义的成员变量,成员方法和构造方法。
成员变量被放在Field[] 数组中
成员方法被放在Method[] 数组中
构造方法被放在Constructor[] 数组中
3.运行时阶段
当类对象被创建以后,就会处在运行时过程中。

获取Class对象的三种方法
1.直接利用全类名Class.forName(“全类名”)方法获取
2.利用类的属性***.class获取
3.利用对象的方法xxx.getClass()获取

获取Class中的成员变量,成员方法,构造方法的方法:
在这里插入图片描述
在这里插入图片描述
其中:
getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
同样类似的还有getConstructors()和getDeclaredConstructors()、getMethods()和getDeclaredMethods(),这两者分别表示获取某个类的方法、构造函数。

以下为Demo示例(Idea实现):
首先创建一个Pojo类,此处示例为Student

public class Student {
    private String name;
    private int id;
    private int age;
    private double money;

    public Student(String name, int id, int age, double money) {
        this.name = name;
        this.id = id;
        this.age = age;
        this.money = money;
    }

    public Student() {
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                ", money=" + money +
                '}';
    }

    public void readBook(){
        System.out.println("读书");
    }

    public void readBook(String bookName){
        System.out.println("读"+bookName);
    }

}

之后写一个Demo测试三种方法:
第一种方法:

        Class cls = Class.forName("com.wl.nuaa.pojo.Student");
        Method[] methods = cls.getMethods();
        for(Method method : methods){
            System.out.println(method);
        }

第二种方法:

          Class cls = Student.class;
          Field[] fields = cls.getDeclaredFields();
          for (Field field : fields){
              System.out.println(field);
          }

第三种方法:

        Student student = new Student();
        Class cls = student.getClass();
        Constructor[] constructors = cls.getConstructors();
        for (Constructor constructor:constructors){
            System.out.println(constructor);
        }

一个反射的案例:
为了解耦,我们利用一个配置文件来操作,让程序根据配置文件给出的数据对进行输出任意类的任意方法。
配置文件内容:

classname=com.wl.nuaa.pojo.Student
methodname=readBook

配置文件与com同级
这里利用一个Demo实现:

        Properties properties = new Properties();
        ClassLoader classLoader = ReflectDemo.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("pro.properties");
        properties.load(is);

        String className = properties.getProperty("classname");
        String methodName = properties.getProperty("methodname");
        
        Class cls = Class.forName(className);
        Object obj = cls.getDeclaredConstructor().newInstance();
        Method method = cls.getDeclaredMethod(methodName);
        method.invoke(obj);

首先需要一个属性文件的对象实例,要利用到类加载器将属性文件加载进来
之后利用className和methodName存放在配置文件中配置的数据值
下面就是利用获取类对象的第一种方法,得到其对象实例,和成员方法,之后利用invoke()实现方法。

在拥有了配置文件以后,如果系统上线,便无需修改代码导致系统重新测试,评估,上线,只需修改配置文件即可达到系统配置修改的目的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值