Java SE | 高级特性 | 反射

反射

反射是框架设计的灵魂~

  • 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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值