Java反射机制是Java语言被视为"准动态"语言的关键性质。Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的内部信息(包括其modifiers(诸如public, static等等)、superclass(例如Object)、实现interfaces(例如Serializable),也包括fields和 methods的所有信息),动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法)。
Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
Object
.
Class类的实例表示正在运行的 Java应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为Class对象的一个类,所有具有相同元素类型和维数的数组都共享该Class对象。基本的Java类型(boolean、byte、 char、short、int、long、float和double)和关键字void也表示为Class对象。
Class没有公共构造方法。Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的。
每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象(更恰当的说,是被保存在一个同名的.class文件中)。如果我们想生成这个类的对象,运行这个程序的Java虚拟机(JVM)将使用类加载器子系统,类加载器首先检查这个类的Class对象是否已经加载。如果尚未加载,默认的类加载器就会根据类名查找.class文件,并将其载入,一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有对象。
获取Class对象有三种方式:
(1) Object类的getClass()方法,例:
Class c1 = new String("").getClass();
当使用Class.forName()方法时,必须提供完全限定类名。即类名要包括所有包名。
Class c4 = int.class;
Class c5 = Double[].class;
boolean.class |
Boolean.TYPE |
char.class |
Character.TYPE |
byte.class |
Byte.TYPE |
short.class |
Short.TYPE |
int.class |
Integer.TYPE |
long.class |
Long.TYPE |
float.class |
Float.TYPE |
double.class |
Double.TYPE |
void.class |
Void.TYPE |
使用Java反射,你可以在运行时检查Java类。检查类是使用反射时经常做的第一件事情。从类中可以获取以下信息:
(1) 类名
(2) 类修饰符 (public, private, synchronized等)
(3) 包信息
(4) 父类
(5) 实现的接口
(6) 构造函数
(7) 方法
(8) 字段
(9) 注解
(10) 内部类
从Class对象中可以获取两个不同的类名。完全限定类名(包括包名)可以使用getName()或getCanonicalName()方法获取,例如:
Class myClazz = MyObject.class;
String className = myClazz.getName();
String className1 = myClazz.getCanonicalName();
如果想要获取不含包名的类名可以使用getSimpleName() 方法,如下:
String simpleClassName = myClazz.getSimpleName();
使用Class对象可以获取一个类的修饰符。类的修饰符即关键字"public","private", "static"等. 如下:
int modifiers = myClazz.getModifiers();
修饰符被包装进一个int内,每一个修饰符都是一个标志位(置位或清零)。可以使用java.lang.reflect.Modifier类中的以下方法来检验修饰符:
Modifier.isAbstract(int modifiers)
Modifier.isFinal(int modifiers)
Modifier.isInterface(int modifiers)
Modifier.isNative(int modifiers)
Modifier.isPrivate(int modifiers)
Modifier.isProtected(int modifiers)
Modifier.isPublic(int modifiers)
Modifier.isStatic(int modifiers)
Modifier.isStrict(int modifiers)
Modifier.isSynchronized(int modifiers)
Modifier.isTransient(int modifiers)
Modifier.isVolatile(int modifiers)
使用Class对象可以获取包信息java.lang.Package,如下:
Package package = myClazz.getPackage();
String packageName = package.getname();
从Package对象中你可以访问诸如名字等包信息。您还可以访问类路径上这个包位于JAR文件中Manifest这个文件中指定的信息。
通过Class对象可以获取类的父类,如下:
Class superclass = myClazz.getSuperclass();
父类的Class对象和其它Class对象一样是一个Class对象,可以继续使用反射。
通过给定的类可以获取这个类所实现的接口列表,如下:
Class[] interfaces = myClazz.getInterfaces();
一个类可以实现多个接口。因此返回一个Class数组。在Java反射机制中,接口也由Class对象表示。
只有给定类声明实现的接口才会返回。例如,如果类A的父类B实现了一个接口C,但类A并没有声明它也实现了C,那么C不会被返回到数组中。即使类A实际上实现了接口C,因为它的父类B实现了C。
为了得到一个给定的类实现接口的完整列表,需要递归访问类和其超类。
//获取一个公有的构造函数,参数为指定参数
public Constructor getConstructor (Class...> parameterTypes)
//获取目标类所有的公有构造函数
public Constructor[]> getConstructors ()
// 获取目标类的一个构造函数,参数为指定参数
public Constructor get DeclaredConstructor (Class...> parameterTypes)
// 获取目标类所有的公有构造函数
public Constructor[]> getDeclaredConstructors ()
//获取该类中的所有函数(不包含从父类继承的函数).
public Method[] getDeclaredMethods ()
//获取该类指定参数的某一公有函数, (包含从父类和接口类继承下来的)
public Method getMethod (String name, Class...> parameterTypes)
//获取该类所有公有函数, (包含从父类和接口类集成下来的函数)
public Method[] getMethods ()
// 获取该 Class 对象中的所有属性( 不包含从父类继承的属性 )
public Method[] getDeclaredFields ()
// 获取指定的Class对象中指定属性名的某一公有属性
public Method getField (String name)
// 获取该Class对象中的所有公有属性 ( 包含从父类和接口类继承下来的公有属性 )
public Method[] getFields ()
// 获取该类某一指定公有注解 public Annotation> A getAnnotation(Class annotationClass)
// 获取该类所有公有注解
public Annotation[] getAnnotations()
// 获取该类某一注解
public Annotation> A getDeclaredAnnotation(Class annotationClass)
// 获取该类所有注解
public Annotation[] getDeclaredAnnotations()
2.10 内部类
// 获取该类公有内部类(包含父类)
public Class>[] getClasses()
// 获取该类所有内部类,包含私有内部类。
public Class>[] getDeclaredClasses()
// 获取该类的外部类
public Class> getDeclaringClass()
2.11 其它方法
isAssignableFrom(Class> cls)
// ([自身类.class]).isInstance([自身类的实例obj]或[其子类的实例obj]) 返回true
// 返回当前clazz是否为成员类;
isMemberClass()
Field对象
表示的字段的值。
abstract |
static int ABSTRACT |
static boolean isAbstract(int mod)
|
final
|
static int FINAL
|
static boolean isFinal
(int mod)
|
interface
|
static int INTERFACE
|
static boolean isInterface
(int mod)
|
native
|
static int NATIVE
|
static boolean isNative
(int mod)
|
private
|
static int PRIVATE
|
static boolean isPrivate
(int mod)
|
protect
|
static int PROTECT
|
static boolean isProtect
(int mod)
|
public
|
static int PUBLIC
|
static boolean isPublic
(int mod)
|
static
|
static int STATIC
|
static boolean isStatic
(int mod)
|
strictfp
|
static int STRICT
|
static boolean isStrict
(int mod)
|
synchronized
|
static int SYNCHRONIZED
|
static boolean isSynchronized
(int mod)
|
transient
|
static int TRANSIENT
|
static boolean isTransient
(int mod)
|
volatile
|
static int VOLATILE
|
static boolean isVolatile
(int mod)
|