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<T> getConstructor (Class...<?> parameterTypes)
//獲取目標類所有的公有構造函數
public Constructor[]<?> getConstructors ()
// 獲取目標類的一個構造函數,參數爲指定參數
public Constructor<T> getDeclaredConstructor (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 <A extends Annotation> A getAnnotation(Class<A> annotationClass)
// 獲取該類所有公有註解
public Annotation[] getAnnotations()
// 獲取該類某一註解
public <A extends Annotation> A getDeclaredAnnotation(Class<A> 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對象
表示的字段的值。
// 返回此Method對象表示的方法的名稱。
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)
|