欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java SE | 高级特性 | 反射

程序员文章站 2022-06-09 20:47:06
...

反射

反射是框架设计的灵魂~

  • JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

  • 要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。

  • 以上的总结就是什么是反射 :反射就是把java类中的各种成分映射成一个个的Java对象。

好处

  1. 运行过程中操作各种类的对象。
  2. 可以解耦,提高可拓展性。

示例

  • 创建一个学生类
public class Student {
    int id;
    public String name;
    public int age;
    public boolean isTrue;

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

    public Student() {
        System.out.println("Student正在完成初始化...");
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public boolean isTrue() {
        return isTrue;
    }

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

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

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

    public void setTrue(boolean aTrue) {
        isTrue = aTrue;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", isTrue=" + isTrue +
                '}';
    }
}
  • 通过反射获取class对象的三种方式
public static void main(String[] args) throws Exception{
        Student stu = new Student();
        // 1.通过对象获取
        Class<? extends Student> cls1 = stu.getClass();
        // 2.通过类名获取
        Class<Student> cls2 = Student.class;
        // 3.通过字符串传参,此中方法可以从配置文件中获取,使用较多
        Class<?> cls3 = Class.forName("demo1.Student");
    }
  • 获取构造方法
public static void main(String[] args) throws Exception{
        // 获取Class对象
        Class<?> cls = Class.forName("demo1.Student");
        // 获取构造方法
        Constructor<?>[] cons = cls.getConstructors();
        for (Constructor<?> c: cons) {
            System.out.println("名称"+":"+c.getName());
            System.out.println("属性长度"+":"+c.getParameters().length);
        }
        
        // 获取有参构造
        Constructor<?> dc1 = cls.getDeclaredConstructor(int.class,String.class,int.class,boolean.class);
        // 获取无参构造
        Constructor<?> dc2 = cls.getDeclaredConstructor();

        // 使用构造
        Object o1 = dc1.newInstance(1, "张三", 16, true);
        System.out.println(o1);

        Object o2 = dc2.newInstance();
        System.out.println(o2);

    }
  • 获取属性
public static void main(String[] args) throws Exception {
        // 创建Class对象
        Class<?> cls = Class.forName("demo1.Student");
        // 获取共有属性
        Field[] fields = cls.getFields();
        for (Field f : fields) {
            System.out.println("属性名:"+f.getName());
            System.out.println("类型:"+ f.getType());
            System.out.println("=========================");
        }

        Field[] dfs = cls.getDeclaredFields();
        for (Field c : dfs) {
            System.out.println("属性名:"+c.getName());
            System.out.println("类型:"+c.getType());
            System.out.println("=========================");
        }

        // 单个属性获取
        Field age = cls.getDeclaredField("age");
        System.out.println(age.getType());

        Object o = cls.getDeclaredConstructor().newInstance();
        age.set(o,25);
        System.out.println(o+"\n");

        // 批量属性获取
        Field[] declaredFields = cls.getDeclaredFields();
        Object o2 = cls.getDeclaredConstructor().newInstance();
        for (Field f : declaredFields) {
            switch (f.getType().getName()) {
                case "int":
                    System.out.println(f.getName());
                    f.set(o2,18);
                    break;
                case "boolean":
                    System.out.println(f.getName());
                    f.set(o2,true);
                    break;
                case "String":
                    System.out.println(f.getName());
                    f.set(o2,"张三");
                    break;
            }
        }
        System.out.println(o2);
    }

通过反射运行配置文件的内容

  • 配置文件
className = demo2.Student
methodName = show
  • show()方法
public class Student {
    public static void show() {
        System.out.println("is show()");
    }
}
  • 测试代码
public class Demo {
    public static void main(String[] args) throws Exception {
        Class<?> className = Class.forName(getValue("className"));
        Method methodName = className.getMethod(getValue("methodName"));
		methodName.invoke(className.getConstructor().newInstance());
    }
    public static String getValue(String key) throws IOException {
        Properties prop = new Properties();
        FileReader fr = new FileReader("./prop/stu.properties");
        prop.load(fr);
        fr.close();
        return prop.getProperty(key);
    }
}
相关标签: 高级特性 java