Java反射API研究(3)——java.lang.Class


  對於反射來說,Class是核心,任何反射的對象都需要通過Class來獲得。

  Class 類的實例表示正在運行的 Java 應用程序中的類和接口。枚舉是一種類,注釋是一種接口。每個數組屬於被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class 對象。基本的 Java 類型(booleanbytecharshortintlongfloatdouble)和關鍵字 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的注解。

 

四、掃描一個包中的所有類


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM