對於反射來說,Class是核心,任何反射的對象都需要通過Class來獲得。
Class
類的實例表示正在運行的 Java 應用程序中的類和接口。枚舉是一種類,注釋是一種接口。每個數組屬於被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class
對象。基本的 Java 類型(boolean
、byte
、char
、short
、int
、long
、float
和 double
)和關鍵字 void
也表示為 Class
對象。
Class
沒有公共構造方法。Class
對象是在加載類時由 Java 虛擬機以及通過調用類加載器中的 defineClass
方法自動構造的。
Class<T>的T
- 由此 Class
對象建模的類的類型。例如,String.class
的類型是 Class<String>
。如果將被建模的類未知,則使用 Class<?>
。
下面來看看如何獲得一個類的Class對象。
有以下幾種方式:
1、調用一個實例的getClass()方法,這個方法是從Object繼承下來的,任何一個對象的實例都可以通過getClass()方法來獲取當前實例的類的Class對象,如果聲明時是父類,則獲取的是真實實例的Class,即子類的Class。
2、通過一個Class對象的Class.getSuperclass(),獲取其父類的Class對象
3、Class的靜態方法forName(String class),這個最常用,通過類名包括包名獲取一個類的class對象,還有個重載方法forName(String name, boolean initialize, ClassLoader loader),第二個參數表示是否初始化該類,即是否執行該類的靜態代碼段,forName(String class)調用的這個方法,默認為true,初始化該類的靜態方法。這在注冊jdbc驅動時有用到。
4、通過一個類的靜態成員獲取class對象,類名.class即可。這個成員對象是jvm加上去的。
5、primitive wrapper classes的TYPE 語法,包裝類可以通過包裝類的TYPE靜態變量來獲取。這里要注意一下:
int.class == Integer.TYPE,但是int.class != Integer.class。經過包裝后,包裝類和原始類的class不是一個對象。
Class對象的所有方法:
<U> Class<? extends U> | asSubclass(Class<U> clazz) | 強制轉換該 Class 對象,以表示指定的 class 對象所表示的類的一個子類。 |
T | cast(Object obj) | 將一個對象強制轉換成此 Class 對象所表示的類或接口。 |
boolean | desiredAssertionStatus() | 如果要在調用此方法時將要初始化該類,則返回將分配給該類的斷言狀態。 |
static Class<?> | forName(String className) | 返回與帶有給定字符串名的類或接口相關聯的 Class 對象。 |
static Class<?> | forName(String name, boolean initialize, ClassLoader loader) | 使用給定的類加載器,返回與帶有給定字符串名的類或接口相關聯的 Class 對象。 |
AnnotatedType[] | getAnnotatedInterfaces() | 返回注釋的AnnotatedType |
AnnotatedType | getAnnotatedSuperclass() | 返回父類的注解的AnnotatedType |
<A extends Annotation> A | getAnnotation(Class<A> annotationClass) | 如果存在該元素的指定類型的注釋,則返回這些注釋,否則返回 null。 |
Annotation[] | getAnnotations() | 返回此元素上存在的所有注釋。 |
<A extends Annotation> A[] | getAnnotationsByType(Class<A> annotationClass) | 返回一個該類型的注解數組 |
String | getCanonicalName() | 返回 Java Language Specification 中所定義的底層類的規范化名稱。 |
Class<?>[] | getClasses() | 返回類定義的公共的內部類,以及從父類、父接口那里繼承來的內部類 |
ClassLoader | getClassLoader() | 返回該類的類加載器。 |
Class<?> | getComponentType() | 返回表示數組組件類型的 Class。如果此類表示數組類,返回表示此類組件類型的 Class。否則返回null。 |
Constructor<T> | getConstructor(Class<?>... parameterTypes) | 返回一個 Constructor 對象,它反映此 Class 對象所表示的類的指定公共構造方法。 |
Constructor<?>[] | getConstructors() | 返回一個包含某些 Constructor 對象的數組,這些對象反映此 Class 對象所表示的類的所有公共構造方法。 |
<A extends Annotation> A | getDeclaredAnnotation(Class<A> annotationClass) | 返回直接存在於此元素上的該類型注釋。 |
Annotation[] | getDeclaredAnnotations() | 返回直接存在於此元素上的所有注釋。 |
<A extends Annotation> A[] | getDeclaredAnnotationsByType(Class<A> annotationClass) | 返回直接存在於此元素上的該類型的注解數組。 |
Class<?>[] | getDeclaredClasses() | 返回類定義的公共的內部類,不包括繼承的。 |
Constructor<T> | getDeclaredConstructor(Class<?>... parameterTypes) | 根據指定參數類型順序返回一個 Constructor 對象,該對象反映此 Class 對象所表示的類或接口的指定構造方法。可獲取非公共構造方法。 |
Constructor<?>[] | getDeclaredConstructors() | 返回 Constructor 對象的一個數組,這些對象反映此 Class 對象表示的類聲明的所有構造方法。不僅是公共的。 |
Field | getDeclaredField(String name) | 返回一個 Field 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明字段。 |
Field[] | getDeclaredFields() | 返回 Field 對象的一個數組,這些對象反映此 Class 對象所表示的類或接口所聲明的所有字段。 |
Method | getDeclaredMethod(String name, Class<?>... parameterTypes) | 返回一個 Method 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明方法。 |
Method[] | getDeclaredMethods() | 返回 Method 對象的一個數組,這些對象反映此 Class 對象表示的類或接口聲明的所有方法,包括公共、保護、默認(包)訪問和私有方法,但不包括繼承的方法。 |
Class<?> | getDeclaringClass() | 如果此 Class 對象所表示的類或接口是另一個類的成員,則返回的 Class 對象表示該對象的聲明類。即返回所在類的class對象,對成員class對象有效。 |
Class<?> | getEnclosingClass() | 返回底層類的立即封閉類。 |
Constructor<?> | getEnclosingConstructor() | 如果該 Class 對象表示構造方法中的一個本地或匿名類,則返回 Constructor 對象,它表示底層類的立即封閉構造方法。 |
Method | getEnclosingMethod() | 如果此 Class 對象表示某一方法中的一個本地或匿名類,則返回 Method 對象,它表示底層類的立即封閉方法。 |
T[] | getEnumConstants() | 如果此 Class 對象不表示枚舉類型,則返回枚舉類的元素或 null。 |
Field | getField(String name) | 返回一個 Field 對象,它反映此 Class 對象所表示的類或接口的指定公共成員字段。 |
Field[] | getFields() | 返回一個包含某些 Field 對象的數組,這些對象反映此 Class 對象所表示的類或接口的所有可訪問公共字段。 |
Type[] | getGenericInterfaces() | 返回表示某些接口的 Type,這些接口由此對象所表示的類或接口直接實現。 |
Type | getGenericSuperclass() | 返回表示此 Class 所表示的實體(類、接口、基本類型或 void)的直接超類的 Type。 |
Class<?>[] | getInterfaces() | 確定此對象所表示的類或接口實現的接口。 |
Method | getMethod(String name, Class<?>... parameterTypes) | 返回一個 Method 對象,它反映此 Class 對象所表示的類或接口的指定公共成員方法。 |
Method[] | getMethods() | 返回一個包含某些 Method 對象的數組,這些對象反映此 Class 對象所表示的類或接口(包括那些由該類或接口聲明的以及從超類和超接口繼承的那些的類或接口)的公共 member 方法。 |
int | getModifiers() | 返回此類或接口以整數編碼的 Java 語言修飾符。 |
String | getName() | 以 String 的形式返回此 Class 對象所表示的實體(類、接口、數組類、基本類型或 void)名稱。 |
Package | getPackage() | 獲取此類的包。 |
ProtectionDomain | getProtectionDomain() | 返回該類的 ProtectionDomain。 |
URL | getResource(String name) | 查找帶有給定名稱的資源。 |
InputStream | getResourceAsStream(String name) | 查找具有給定名稱的資源。 |
Object[] | getSigners() | 獲取此類的標記。 |
String | getSimpleName() | 返回源代碼中給出的底層類的簡稱。 |
Class<? super T> | getSuperclass() | 返回表示此 Class 所表示的實體(類、接口、基本類型或 void)的超類的 Class。 |
String | getTypeName() | 返回該類型的名稱 |
TypeVariable<Class<T>>[] | getTypeParameters() | 按聲明順序返回 TypeVariable 對象的一個數組,這些對象表示用此 GenericDeclaration 對象所表示的常規聲明來聲明的類型變量。 |
boolean | isAnnotation() | 如果此 Class 對象表示一個注釋類型則返回 true。 |
boolean | isAnnotationPresent(Class<? extends Annotation> annotationClass) | 如果指定類型的注釋存在於此元素上,則返回 true,否則返回 false。 |
boolean | isAnonymousClass() | 當且僅當底層類是匿名類時返回 true。 |
boolean | isArray() | 判定此 Class 對象是否表示一個數組類。 |
boolean | isAssignableFrom(Class<?> cls) | 判定此 Class 對象所表示的類或接口與指定的 Class 參數所表示的類或接口是否相同,或是否是其超類或超接口。 |
boolean | isEnum() | 當且僅當該類聲明為源代碼中的枚舉時返回 true。 |
boolean | isInstance(Object obj) | 判定指定的 Object 是否與此 Class 所表示的對象賦值兼容。 |
boolean | isInterface() | 判定指定的 Class 對象是否表示一個接口類型。 |
boolean | isLocalClass() | 當且僅當底層類是本地類時返回 true。 |
boolean | isMemberClass() | 當且僅當底層類是成員類時返回 true。 |
boolean | isPrimitive() | 判定指定的 Class 對象是否表示一個基本類型。 |
boolean | isSynthetic() | 如果此類是復合類,則返回 true,否則 false。有匿名類部類的類可以稱作為復合類。 |
T | newInstance() | 調用默認構造方法創建此 Class 對象所表示的類的一個新實例。 |
String | toGenericString() | 返回該對象的描述,包含標識符等。 |
比較重要的方法:newInstance(),創建一個該類的實例,調用默認構造方法。
特殊的:
1、獲取一個類聲明時的確切泛型類型:
class Parameterized<T,V,Z>{ } Type classType = abstractTransfer.getClass().getGenericSuperclass(); Type[] ret = ((ParameterizedType)classType).getActualTypeArguments(); T = (Class) ret[0]; V = (Class) ret[1]; Z = (Class) ret[2];
2、運行時獲取一個被代理的類的真實類對象
TrueClass proxyClass = proxy;
Class trueClass = proxyClass.getClass().getSuperclass();
二、ClassLoader對象
參考http://blog.chinaunix.net/uid-21227800-id-65879.html
類加載器是負責加載類的對象。ClassLoader 類是一個抽象類。如果給定類的二進制名稱,那么類加載器會試圖查找或生成構成類定義的數據。一般策略是將名稱轉換為某個文件名,然后從文件系統讀取該名稱的“類文件”。
每個 Class 對象都包含一個對定義它的 ClassLoader 的引用。
數組類的 Class 對象不是由類加載器創建的,而是由 Java 運行時根據需要自動創建。數組類的類加載器由 Class.getClassLoader() 返回,該加載器與其元素類型的類加載器是相同的;如果該元素類型是基本類型,則該數組類沒有類加載器。
獲取ClassLoader對象的幾種方法:
1、通過Thread對象的getContextClassLoader()獲取類加載器。一般為Thread.currentThread().getContextClassLoader()。 當前類的ClassLoader
2、通過Class對象的getClassLoader()方法獲取類加載器。一般為this.getClass().getClassLoader()。 當前線程的ClassLoader
3、通過ClassLoader類的靜態方法ClassLoader.getSystemClassLoader()方法。 系統ClassLoader,即系統的入口點所使用的ClassLoader。(注意,system ClassLoader與根ClassLoader並不一樣。JVM下system ClassLoader通常為App ClassLoader)
這三個是否引用的同一對象呢?一般情況下是的,因為都返回True,其他高級應用中可能會不一樣。
這個對象中還有很多操作資源的方法比較有用,自行查閱。
三、Package對象
Package 對象包含有關 Java 包的實現和規范的版本信息。通過用於加載類的 ClassLoader 實例,可以獲取並獲得此版本信息。通常,此信息存儲在與類一起分發的清單中。
可以讀Package的注解。
四、掃描一個包中的所有類