初识反射
什么是反射
简单来说,反射就是把类的各个部分进行解析然后封装成对应的对象(Field, Method和Constructor对象),通过这些对象可以做一些事情。
Class类对象
Class类对象是反射技术的核心对象。通过API文档我们知道Class类就是一个普通的类。只不过它是用来描述类的而已。而且它没有构造器它是在类加载阶段由类加载器来自动构造出来的。
通过这个Class类对象就可以获取该类解析后封装的各个对象。例如该类的字段对象(Field)、构造器对象(Constructor)和方法对象(Method)等。然后就可以获取到类本身的所有信息,甚至可以修改类本身!
实际上该技术我们可以理解为类在照镜子,而镜子里面反射出来的镜像就是该类对应的Class类对象。通过镜子里面的自己(Class类对象)就可以看清自己(类本身)。所以该技术被形象的称为反射。
反射的用处
总的来说反射技术赋予了JAVA这类静态语言重要的动态性。
反射是如何赋予java动态性的呢?1.反射可以在程序运行时解剖任何类(获取类的任何信息和改变字段的值) 2.反射可以在程序运行时加载类
基于以上两点反射赋予了Java语言动态性。
下面举两个栗子说明下!
首先我们要知道java(静态语言)类型判断是在运行前判断(如编译阶段)的。运行前就已经把类型定死了。程序的扩展性就很差。
1.例如IDEA是我们常用的开发工具。他的本质就是一段程序。当你打开编译器时这些代码就在执行,但是你有没有这个"奇怪"的现象。
这个不是我们常用的代码提示功能吗?就这?
但是你有没有想过,他是咋样实现的。当IDEA打开时程序其实已经执行了,IDEA事先不知道我们会打下"String."这行代码,当我们打下这行代码是,IDEA会在运行时加载String类获取String对应的Class类对象.然后通过Class类对象来解剖String类,然后将方法名现实成列表即可。这样就可以大大提高程序的扩展性(对于任何的类都可以进行代码提示)。
2.我们在学习Spring时最开始的一个概念就是IOC(控制反转)。简单来说就是通过外部文件的配置来让Spring容器来管理JAVABean.但是你有没有想过Spring框架运行前知道要加载那些JAVABean吗?它不知道! Spring框架在运行时会读取配置文件,然后通过配置文件中需要加载类的全类名,通过反射技术加载并创建JAVABean。
以上两个栗子都是在程序运行期间才会知道该加载解析那个类,而不是在编译器就决定的。这样做就可以大大提高程序的扩展性(对于任何的类都可以进行代码提示和加载产生任意的JAVABean).这就是反射技术的重要性,想象下没有反射技术该是多么可怕的事情!
反射的用法
Class类对象的获取
获取对应Class类的方法
方法名 | 方法描述 |
---|
Class getClass() | Object类的一个方法,所以每一个类都有该方法。一般是在有对象实例时来获取类对象时使用的方法 |
Class forName(String) | Class类的一个静态方法,通过类的全类名来获取类对象 |
class静态常量 | 一般是知道该类的类型时,直接访问calss静态常量就可以获取class类对象 |
Class类的用法
方法名 | 方法描述 |
---|
Field getField(String name) | 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。 |
Field[] getFields() | 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。 |
Field[] getDeclaredFields() | 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段。 |
Method[] getMethod((String name, Class… parameterTypes) | 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 |
Method[] getMethods() | 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共成员方法。 |
Method[] getDeclaredMethods() | 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 |
Constructor[] getConstructor(Class… parameterTypes) | 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。 |
Constructor[] getConstructors() | 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。 |
Constructor[] getDeclaredConstructors() | 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。 |
T newInstance() | 创建此 Class 对象所表示的类的一个新实例(无参构造)。 |
String getName() | 以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。 |
String getSimpleName() | 返回源代码中给出的基础类的简称。 |
Annotation[] getAnnotations() | 返回类的所有注解信息 |
int getModifiers() | 返回此类或接口以整数编码的 Java 语言修饰符。 |
Field类的用法
方法名 | 方法描述 |
---|
Object get(Object obj) | 返回指定对象上此 Field 表示的字段的值 |
void set(Object obj, Object value) | 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 |
void setAccessible(boolean flag) | 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。 |
int getModifiers() | 以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符。 |
Class<?> getType() | 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型 |
String getName() | 返回此 Field 对象表示的字段的名称。 |
Method的用法
方法名 | 方法描述 |
---|
Object invoke(Object obj, Object… args) | 对带有指定参数的指定对象调用由此 Method 对象表示的基础方法。 |
void setAccessible(boolean flag) | 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。 |
int getModifiers() | 以整数形式返回此 Method 对象所表示方法的 Java 语言修饰符。 |
Class<?> getReturnType() | 返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的返回值类型。 |
String getName() | 以 String 形式返回此 Method 对象表示的方法名称。 |
Class<?>[] getParameterTypes() | 按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。 |
Constructor的用法
方法名 | 方法描述 |
---|
T newInstance(Object… initargs) | 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。 |
void setAccessible(boolean flag) | 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。 |
int getModifiers() | 以整数形式返回此 Constructor 对象所表示构造方法的 Java 语言修饰符。 |
String getName() | 以字符串形式返回此构造方法的名称。 |
Class<?>[] getParameterTypes() | 按照声明顺序返回一组 Class 对象,这些对象表示此 Constructor 对象所表示构造方法的形参类型。 |
Modifier的用法
Modifier 类提供了 static 方法和常量,对类和成员访问修饰符进行解码。修饰符集被表示为整数,用不同的位位置 (bit position) 表示不同的修饰符。
方法名 | 方法描述 |
---|
static boolean isAbstract(int mod) | 如果整数参数包括 abstract 修饰符,则返回 true,否则返回 false。 |
static boolean isFinal(int mod) | 如果整数参数包括 interface 修饰符,则返回 true,否则返回 false。 |
static boolean isPublic(int mod) | 如果整数参数包括 public 修饰符,则返回 true,否则返回 false。 |
static boolean isPrivate(int mod) | 如果整数参数包括 private 修饰符,则返回 true,否则返回 false。 |
static boolean isXXX(int mod) | 如果整数参数包括 XXX修饰符,则返回 true,否则返回 false。 |
static String toString(int mod) | 返回描述指定修饰符中的访问修饰符标志的字符串。 |