Java反射

反射Reflect

反射介绍及作用

  • 反射是在运行时动态访问类与对象的技术
  • JDK1.2版本后的高级特性,属于java.lang.reflect
  • 大多数Java框架都基于反射实现参数配置、动态注入等特性

反射四个核心类

  • Class类
  • Constructor构造方法类
  • Method方法类
  • Field成员变量类

Class类

  • Class是JVM中代表"类和接口"的类
  • Class对象具体包含了某个特定类的结构信息
  • 通过Class对象可获取对应类的构造方法/方法/成员变量

Class核心方法

方法用途
Class.forName()静态方法 用于获取指定Class对象
ClassObj.newInstance()通过默认构造方法创建新的对象
ClassObj.getConstructor()获取指定的public修饰构造方法Constructor对象
ClassObj.getMethod()获取指定的public修饰方法Method对象
ClassObj.getField()获取指定的public修饰成员变量Field对象
   try {
            // Class.forName()方法将指定的类加载到jvm 并返回对应Class对象
            Class employee = Class.forName("com.xs.reflect.Employee");
            // .newInstance() 通过默认构造方法创建新的对象
            employee.newInstance();
        } catch (ClassNotFoundException e) {
            // 类名或类路径名书写错误
            e.printStackTrace();
        } catch (InstantiationException e) {
            // 对象无法被实例化
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // 访问权限异常 作用域外访问对象方法或成员变量时
            e.printStackTrace();
        }

Constructor构造方法类

  • Contructor类是对Java类中的构造方法的抽象
  • Contructor对象包含了具体类的某个具体构造方法的声明
  • 通过Contructor对象调用带参构造方法创建对象
方法用途
classObj.getConstructor()获取指定public修饰的构造方法对象
constructorObj.newInstance()通过对应的构造方法创建对象
try {
            Class eclass = Class.forName("com.xs.reflect.Employee");
            // 1.获取 Constructor 对象 传入类类型数组
            Constructor constructor = eclass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            // 2.根据 Constructor 对象 生成实例传入对应的参数
            Employee employee = (Employee) constructor.newInstance(100, "李磊", 13000f, "研发部");
            System.out.println(employee);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // 找不到 对应参数的构造函数
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

Method方法类

  • Method对象指代某个类中的方法的描述
  • Method对象使用classObj.getMethod()方法获取
  • 通过Method对象调用指定对象的对应方法
方法用途
classObj.getMethod()获取指定public修饰的方法对象
methodObj.invoke()调用指定对象的对应方法
public static void main(String[] args) {
        try {
            Class eclass = Class.forName("com.xs.reflect.Employee");
            // 1.获取 Constructor 对象 传入类类型数组
            Constructor constructor = eclass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            // 2.根据 Constructor 对象 生成实例传入对应的参数
            Employee employee = (Employee) constructor.newInstance(100, "李磊", 13000f, "研发部");
            System.out.println(employee);

            // 3.通过 Class实例调用 getMethod 传入要调用的方法以及参数类型
            Method method = eclass.getMethod("updateSalary", new Class[]{Float.class});
            // 4. 将获取到的 method 对象 调用invoke 执行对应的方法 传入要操作的对象 以及 参数
            Employee employee1 = (Employee) method.invoke(employee, 2000f);
            System.out.println(employee1);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // 找不到 对于参数的构造函数
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

Field成员变量类

  • Field对应某个具体类中的成员变量的声明
  • Field对象使用classObj.getField()方法获取
  • 通过Field对象可为某对象成员变量赋值/取值

Field类核心方法

方法用途
classObj.getField()获取指定public修饰的成员变量对象
fieldObj.set()为某对象指定成员变量赋值
fieldObj.get()获取某对象指定成员变量数值
 try {
            Class eclass = Class.forName("com.xs.reflect.Employee");
            // 1.获取 Constructor 对象 传入类类型数组
            Constructor constructor = eclass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            // 2.根据 Constructor 对象 生成实例传入对应的参数
            Employee employee = (Employee) constructor.newInstance(100, "李磊", 13000f, "研发部");
            System.out.println(employee);
            // 3.通过 Class实例调用 getField 传入要获取的类属性
            Field field = eclass.getField("emame");
            // 4.通过获取的Field对象get 对应对象的属性值
            String ename = (String) field.get(employee);
            System.out.println("ename: "+ename);
            // 5. 通过获取的Field对象set 对应对象的属性值
            field.set(employee,"吕小波");
            ename = (String) field.get(employee);
            System.out.println("ename: " + ename);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // 找不到 对于参数的构造函数
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
     	// 没有找到对应成员变量的异常
            e.printStackTrace();
        }

getDeclared系列方法

  • getDeclaredConstructor(s)|Method(s)|Field(s) 获取对应对象
  • getConstructor(s)|Method(s)|Field(s)只能获取public对象
  • 访问非作用域内构造方法 方法 成员变量会抛出异常
   try {
            Class eclass = Class.forName("com.xs.reflect.Employee");
            // 1.获取 Constructor 对象 传入类类型数组
            Constructor constructor = eclass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            // 2.根据 Constructor 对象 生成实例传入对应的参数
            Employee employee = (Employee) constructor.newInstance(100, "李磊", 13000f, "研发部");
            System.out.println(employee);
            // getDeclaredFields 返回所有的成员变量
            Field[] fields = eclass.getDeclaredFields();
            for (Field field : fields) {
                if (field.getModifiers() == 1) {// public
                    Object obj = field.get(employee);
                    System.out.println(field.getName() + obj);
                } else if (field.getModifiers() == 2) {// private
                    Method method = eclass.getMethod("get" + field.getName().substring(0, 1).toUpperCase(Locale.ROOT) + field.getName().substring(1));
                    Object obj = method.invoke(employee);
                    System.out.println("get方法获取的值"+field.getName() + obj);
                }
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // 找不到 对于参数的构造函数
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值