赞
踩
目录
Java
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java
语言的反射机制。简单来说,反射机制指的是程序在运行时能够获取自身的信息。在Java
中,只要给定类的名字,就可以通过反射机制来获得类的所有信息。Java
反射机制主要提供了以下功能,这些功能都位于java.lang.reflect
包。
要想知道一个类的属性和方法,必须先获取到该类的字节码文件对象。获取类的信息时,使用的就是Class
类中的方法。所以先要获取到每一个字节码文件(.class
)对应的Class
类型的对象.
Java反射机制的优缺点
优点:
Java
动态编译相结合,可以实现无比强大的功能。Java
这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。缺点:
与Java-Reflection相关种类主要分为:
类名 | 用途 |
---|---|
Class类 | 代表类的实体,在运行的Java应用程序中表示类和接口 |
Field类 | 代表类的成员变量(成员变量也称为类的属性) |
Method类 | 代表类的方法 |
Constructor类 | 代表类的构造方法 |
Annotation类 | 代表类的注解 |
实现java
反射机制的类都位于java.lang.reflect
包中,java.lang.Class
类是Java
反射机制API
中的核心类。
java.lang.Class
类是实现反射的关键所在,Class
类的一个实例表示Java
的一种数据类型,包括类、接口、枚举、注解(Annotation
)、数组、基本数据类型和void
。Class
没有公有的构造方法,Class
实例是由JVM
在类加载时自动创建的。
在程序代码中获得Class
实例可以通过如下代码实现:
- // 1. 通过类型class静态变量
- Class clz1 = String.class;
- String instance1 = clz1.newInstance();
- // 2. 通过对象的getClass()方法
- String str2 = "Hello";
- Class clz2 = str2.getClass();
- String instance2 = clz2.newInstance();
- //
每一种类型包括类和接口等,都有一个class
静态变量可以获得Class
实例。另外,每一个对象都有getClass()
方法可以获得Class
实例,该方法是由Object
类提供的实例方法。
Object
类的getClass()
方法class
Class
类中的静态方法forName()
java.lang.reflect
包提供了反射中用到类,主要的类说明如下:
Constructor
类:提供类的构造方法信息。Field
类:提供类或接口中成员变量信息。Method
类:提供类或接口成员方法信息。Array
类:提供了动态创建和访问Java
数组的方法。Modifier
类:提供类和成员访问修饰符信息。为了能够动态获取对象构造方法的信息,首先需要通过下列方法之一创建一个Constructor
类型的对象或者数组。
创建的每个Constructor
对象表示一个构造方法,然后利用Constructor
对象的方法操作构造方法。
getConstructors()和getDeclaredConstructors()区别
getConstructors():获得某个类的所有的公共(public)的构造方法,包括父类中的构造方法。
getDeclaredConstructors():获得某个类的所有声明的构造方法,即包括public、private和proteced,但是不包括父类的申明构造方法。
同样类似的还有getMethods()和getDeclaredMethods()。
Constructor
类的常用方法
方法名称 | 说明 |
---|---|
isVarArgs() | 查看该构造方法是否允许带可变数量的参数,如果允许,返回true ,否则返回false |
getParameterTypes() | 按照声明顺序以Class 数组的形式获取该构造方法各个参数的类型 |
通过java.lang.reflect.Modifier
类可以解析出getMocMers()
方法的返回值所表示的修饰符信息。在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,还可以字符串的形式获得所有修饰符。
静态方法名称 | 说明 |
---|---|
isStatic(int mod) | 如果使用 static 修饰符修饰则返回 true,否则返回 false |
isPublic(int mod) | 如果使用 public 修饰符修饰则返回 true,否则返回 false |
isProtected(int mod) | 如果使用 protected 修饰符修饰则返回 true,否则返回 false |
isPrivate(int mod) | 如果使用 private 修饰符修饰则返回 true,否则返回 false |
isFinal(int mod) | 如果使用 final 修饰符修饰则返回 true,否则返回 false |
toString(int mod) | 以字符串形式返回所有修饰符 |
我们可以通过Class
对象来获取Constructor
类的实例:
- Class aClass = ...//获取Class对象
- Constructor[] constructors = aClass.getConstructors();
返回的Constructor
数组包含每一个声明为公有的(Public
)构造方法。
如果你知道你要访问的构造方法的方法参数类型,你可以用下面的方法获取指定的构造方法,这例子返回的构造方法的方法参数为String
类型:
- Class aClass = ...//获取Class对象
- Constructor constructor = aClass.getConstructor(new Class[]{String.class});
如果没有指定的构造方法能满足匹配的方法参数则会抛出:NoSuchMethodException
。
你可以通过如下方式获取指定构造方法的方法参数信息:
- Constructor constructor = ... //获取Constructor对象
- Class[] parameterTypes = constructor.getParameterTypes();
你可以通过如下方法实例化一个类:
- Constructor constructor = MyObject.class.getConstructor(String.class);
- MyObject myObject = (MyObject)constructor.newInstance("constructor-arg1");
constructor.newInstance()
方法的方法参数是一个可变参数列表,但是当你调用构造方法的时候你必须提供精确的参数,即形参与实参必须一一对应。在这个例子中构造方法需要一个String
类型的参数,那我们在调用newInstance
方法的时候就必须传入一个String
类型的参数。
要动态获取一个对象方法的信息,首先需要通过下列方法之一创建一个Method
类型的对象或者数组。
静态方法名称 | 说明 |
---|---|
getName() | 获取该方法的名称 |
getParameterType() | 按照声明顺序以 Class 数组的形式返回该方法各个参数的类型 |
getReturnType() | 以 Class 对象的形式获得该方法的返回值类型 |
getExceptionTypes() | 以 Class 数组的形式获得该方法可能抛出的异常类型 |
invoke(Object obj,Object...args) | 利用 args 参数执行指定对象 obj 中的该方法,返回值为 Object 类型 |
isVarArgs() | 查看该方法是否允许带有可变数量的参数,如果允许返回 true,否则返回 false |
getModifiers() | 获得可以解析出该方法所采用修饰符的整数 |
可以通过Class
对象获取Method
对象,如下例:
- Class aClass = ...//获取Class对象
- Method[] meth
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。