java反射机制

今⽇内容
反射:框架设计的灵魂
测试的数据:

  • 框架:半成品软件。可以在框架的基础上进⾏软件开发,简化编码
  • 反射:将类的各个组成部分封装为其他对象,这就是反射机制
  • 好处:
  1. 可以在程序运⾏过程中,操作这些对象。
  2. 可以解耦,提⾼程序的可扩展性。后期学习的ssh框架等框架都会⽤来
  • 获取Class对象的⽅式:
  1. Class.forName(“全类名”):将字节码⽂件加载进内存,返回Class对象
  • 多⽤于配置⽂件,将类名定义在配置⽂件中。读取⽂件,加载类
  1. 类名.class:通过类名的属性class获取
  • 多⽤于参数的传递,android
  1. 对象.getClass():getClass()⽅法在Object类中定义着。
  • 多⽤于对象的获取字节码的⽅式
  • 结论:
    同⼀个字节码⽂件(.class)在⼀次程序运⾏过程中,只会被加载⼀次,不论通过哪⼀种⽅式获取的Class对象
    都是同⼀个。
    package domain;
    public class Person {
    private String name;
    private int age;
    public String a;
    protected String b;
    String c;
    private String d;
    public Person() {
    }
    public Person(String name, int age) {
    this.name = name;
    this.age = age;
    }
    public String getName() { return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public int getAge() {
    return age;
    }
    public void setAge(int age) {
    this.age = age;
    }
    @Override
    public String toString() {
    return “Person{” +
    “name=’” + name + ‘’’ +
    “, age=” + age +
    “, a=’” + a + ‘’’ +
    “, b=’” + b + ‘’’ +
    “, c=’” + c + ‘’’ +
    “, d=’” + d + ‘’’ +
    ‘}’;
    }
    public void eat(){
    System.out.println(“eat…”);
    }
    public void eat(String food){
    System.out.println(“eat…”+food);
    }
    }
    package domain;
    public class Student {
    public void sleep(){
    System.out.println(“sleep…”);
    }
    }
    Class对象功能:
  • 获取功能:
  1. 获取成员变量们
  • Field[] getFields() :获取所有public修饰的成员变量
  • Field getField(String name) 获取指定名称的 public修饰的成员变量
    //1.Class.forName(“全类名”)
    Class cls1 = Class.forName(“domain.Person”);
    System.out.println(cls1);
    //2.类名.class
    Class cls2 = Person.class;
    System.out.println(cls2);
    //3.对象.getClass()
    Person p = new Person();
    Class cls3 = p.getClass();
    System.out.println(cls3);
    //== ⽐较三个对象
    System.out.println(cls1 == cls2);//true
    System.out.println(cls1 == cls3);//true
    //不同的字节码的Class对象不同
    Class c = Student.class;
    System.out.println(c == cls1);//false
  • Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
  • Field getDeclaredField(String name)
  1. 获取构造⽅法们
  • Constructor<?>[] getConstructors()
  • Constructor getConstructor(类<?>… parameterTypes)
  • Constructor getDeclaredConstructor(类<?>… parameterTypes)
  • Constructor<?>[] getDeclaredConstructors()
  1. 获取成员⽅法们:
  • Method[] getMethods()
  • Method getMethod(String name, 类<?>… parameterTypes)
  • Method[] getDeclaredMethods()
  • Method getDeclaredMethod(String name, 类<?>… parameterTypes)
  1. 获取全类名
  • String getName() 获取所有public 修饰的成员变量
    操作某⼀个字段:a
    获取所有的成员变量,不考虑修饰符
    获取构造⽅法:
    //0.获取Person的Class对象
    Class personClass = Person.class;
    //1.Field[] getFields()获取所有public修饰的成员变量
    Field[] fields = personClass.getFields();
    for (Field field : fields) {
    System.out.println(field);
    }
    //2.Field getField(String name)
    Field a = personClass.getField(“a”);
    //获取成员变量a 的值
    Person p = new Person();
    Object value = a.get§;
    System.out.println(value);
    //设置a的值
    a.set(p,“张三”);
    System.out.println§;
    //0.获取Person的Class对象
    Class personClass = Person.class;
    Person p = new Person();
    //Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
    Field[] declaredFields = personClass.getDeclaredFields();
    for (Field declaredField : declaredFields) {
    System.out.println(declaredField);
    }
    //Field getDeclaredField(String name)
    Field d = personClass.getDeclaredField(“d”);
    //忽略访问权限修饰符的安全检查
    d.setAccessible(true);//暴⼒反射,注意私有的要加这个
    Object value2 = d.get§;
    System.out.println(value2);初始化空的构造
    获取指定名称的⽅法并执⾏
    //0.获取Person的Class对象
    Class personClass = Person.class;
    //Constructor getConstructor(类<?>… parameterTypes)
    //获取参数是String,int的构造⽅法
    Constructor constructor = personClass.getConstructor(String.class, int.class);
    System.out.println(constructor);
    //创建对象
    Object person = constructor.newInstance(“张三”, 23);
    System.out.println(person);
    //0.获取Person的Class对象
    Class personClass = Person.class;
    Constructor constructor1 = personClass.getConstructor();
    System.out.println(constructor1);
    //创建对象
    Object person1 = constructor1.newInstance();
    System.out.println(person1);
    Object o = personClass.newInstance();
    System.out.println(o);
    //constructor1.setAccessible(true);
    //0.获取Person的Class对象
    Class personClass = Person.class;
    //获取指定名称的⽅法
    Method eat_method = personClass.getMethod(“eat”);
    Person p = new Person();
    //执⾏⽅法
    eat_method.invoke§;
    Method eat_method2 = personClass.getMethod(“eat”, String.class);
    //执⾏⽅法
    eat_method2.invoke(p,“饭”);获取所有public修饰的⽅法
    获取类名
    //0.获取Person的Class对象
    Class personClass = Person.class;
    Method[] methods = personClass.getMethods();
    for (Method method : methods) {
    System.out.println(method);
    String name = method.getName();
    System.out.println(name);
    //method.setAccessible(true);
    }
    String className = personClass.getName();
    System.out.println(className);
  • Field:成员变量
  • 操作:
  1. 设置值
  • void set(Object obj, Object value)
  1. 获取值
  • get(Object obj)
  1. 忽略访问权限修饰符的安全检查
  • setAccessible(true):暴⼒反射
  • Constructor:构造⽅法
  • 创建对象:
  • T newInstance(Object… initargs)
  • 如果使⽤空参数构造⽅法创建对象,操作可以简化:Class对象的newInstance⽅法
  • Method:⽅法对象
  • 执⾏⽅法:
  • Object invoke(Object obj, Object… args)
  • 获取⽅法名称:
  • String getName:获取⽅法名* 案例:
  • 需求:写⼀个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执⾏其中任意⽅法
  • 实现:
  1. 配置⽂件
  2. 反射
  • 步骤:
  1. 将需要创建的对象的全类名和需要执⾏的⽅法定义在配置⽂件中
  2. 在程序中加载读取配置⽂件
  3. 使⽤反射技术来加载类⽂件进内存
  4. 创建对象
  5. 执⾏⽅法
    //可以创建任意类的对象,可以执⾏任意⽅法
    /*
    前提:不能改变该类的任何代码。可以创建任意类的对象,可以执⾏任意⽅法
    /
    /
    Person p = new Person();
    p.eat();/
    /

    Student stu = new Student();
    stu.sleep();*/
    //读取配置信息
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new
    FileInputStream(“test.config”)));
    String content = bufferedReader.readLine();
    //Person:eat
    //3.加载该类进内存
    Class cls = Class.forName(content.split("😊[0]);
    //4.创建对象
    Object obj = cls.newInstance();
    //5.获取⽅法对象
    Method method = cls.getMethod(content.split("😊[1]);
    //6.执⾏⽅法
    method.invoke(obj);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值