帮你理清楚Java反射应该如何写

JAVA反射的概念百度百科对Java反射的定义:JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制 。
举一个我使用到反射的例子:有一个类,它内部用一个private方法获取到了原始信息,然后在对外public方法中将数据过滤返回 。我现在想拿到原始数据,通过普通途径是拿不到的,这时候就可以通过反射实现 。
Java反射涉及到4个类和一个接口 。四个类是Class类、Field类、Method类、Constructor类(后面三个类都属于Java 反射类库java.lang.reflect),一个接口是Member接口 。

  • Class类:实现反射功能是通过下面三个类和一个接口的 。那么为什么需要Class类呢?第一,JVM创建对象之前必须加载该类的Class对象 。第二,看源码可以发现,下面三个类是没有public构造器的,也就是说下面三个类的对象只能通过Class类来获取 。
  • Constructor类:实现了Member接口 。该类针对构造器 。主要提供创建对象的功能 。
  • Field类:实现了Member接口 。该类针对属性 。该类提供了获取属性的类型、修饰符、注解、变量名、值以及修改属性值的功能(包括private属性)
  • Method类:实现了Member接口 。该类针对方法 。该类提供了获取方法返回类型、方法参数类型、方法参数名称、方法抛出异常类型、方法修饰符,以及通过反射调用方法等功能 。
  • Member接口:该类提供了一个方法AccessibleObject 。所以实现类的对象都可以使用该方法取消 Java 语言访问权限检查 。
一般使用反射,代码步骤就是:
  1. 获取目标类的Class对象
  2. 通过Class对象获取Field对象或者Method对象或者Constructor对象
  3. 使用Field对象或者Method对象或者Constructor对象调用实现的Member接口的AccessibleObject方法去交访问权限检查
  4. Field对象或者Method对象或者Constructor对象进行反射操作
For Example有这样一个类,可以看到其构造器、属性和方法都是私有的(toString方法是一会儿用来验证的),普通的手段是无法使用这个类的 。
帮你理清楚Java反射应该如何写

文章插图
目标类
现在通过反射来使用这个类:
帮你理清楚Java反射应该如何写

文章插图
通过反射操作构造器、方法、属性
最后看一下运行结果:
帮你理清楚Java反射应该如何写

文章插图
运行结果
接口整理看了上面的例子应该对Java反射有了整体的理解 。但上面的例子仍旧太简单了,因为Java反射还提供了很多其他的接口可供调用 。
获取Class对象
上面例子中是一种获取Class对象的方式,获取Class对象的方式有很多种:
帮你理清楚Java反射应该如何写

文章插图
常见的获取Class对象的方法
Constructor对象
Class提供4种获取Constructor对象的方法 。
//获取指定的构造器(任何访问类型的构造器、注意是可变参数)Class.getDeclaredConstructor(Class<?>... parameterTypes);//获取指定的public构造器(注意是可变参数)Class.getConstructor(Class<?>... parameterTypes);//获取所有构造器(任何访问类型的构造器),返回Constructor数组Class.getDeclaredConstructors();//获取所有public构造器,返回Constructor数组Class.getConstructors();Field对象
Class提供4种获取Field对象的方法 。
和获取Constructor对象类似 。
现在再看看上面写的:
Field类:实现了Member接口 。该类针对属性 。该类提供了获取属性的类型、修饰符、注解、变量名、值以及修改属性值的功能(包括private属性)
例子种修改属性值是通过set方法实现的 。其他提到的这些功能,Field都有相应的方法可供调用 。只需简单查询接口文档即可 。
获取Method对象
【帮你理清楚Java反射应该如何写】Class提供4种获取Method对象的方法 。
和获取Constructor对象类似 。
Method类:实现了Member接口 。该类针对方法 。该类提供了获取方法返回类型、方法参数类型、方法参数名称、方法抛出异常类型、方法修饰符,以及通过反射调用方法等功能 。
例子中通过反射调用方法使用的是invoke()方法 。其他提到的功能,Method都有相应的方法可供调用 。只需要简单的查询接口文档即可 。


推荐阅读