java.lang.Class使用中文文檔

Class類是反射與加載器最常用的核心類,最近計劃寫一個JAVA加載器框架,決定重新溫習(xí)相關(guān)接口和類的源碼文檔,實踐相關(guān)用法以消除心中所存不確定。

  • 目錄結(jié)構(gòu)
  1. 類說明
  2. 對象創(chuàng)建
  3. UML類圖
  4. 類成員方法
  5. 學(xué)習(xí)總結(jié)

1 類說明

翻譯Class類源碼英文文檔,分段翻譯并配合理解和例子加深印象。

英文:Instances of the class {@code Class} represent classes and interfaces in a running Java application.
中文:在一個運行中的JAVA程序,Class類的實例,代表用關(guān)鍵字class或interface聲明的對象,如public class AnyObjectpublic interface AnyInterface

英文:An enum is a kind of class and an annotation is a kind of interface.
中文:Enum-枚舉是一種Class類型,Annotation-注解是一種接口類型。

英文:Every array also belongs to a class that is reflected as a {@code Class} object that is shared by all arrays with the same element type and number of dimensions.
中文:每一個數(shù)組屬于一個類,按照數(shù)組元素類型和維度被反射為一個類對象,這個類對象被具有相同元素類型和維度的數(shù)組共享。

應(yīng)用理解

序號 變量聲明 變量聲明 是否相同 差異因素
1 String[] o1 = new String[3] String[] o2 = new String[10] 相同
2 String[] o1 = new String[3] String[][] o3 = new String[3][5] 不同 數(shù)組維度
3 String[] o1 = new String[3] byte[] o4 = new byte[1024] 不同 元素類型

英文:The primitive Java types ({@code boolean}, {@code byte}, {@code char}, {@code short},{@code int}, {@code long}, {@code float}, and {@code double}), and the keyword {@code void} are also represented as {@code Class} objects.
中文:JAVA原始類型boolean / byte / char / short / int / long / float / double 與void關(guān)鍵字,也都有一種類對象代表。

原始類型與類對象對應(yīng)表

序號 原始類型 對象類型 類型縮寫
1 boolean java.lang.Boolean Z
2 byte java.lang.Byte B
3 char java.lang.Character C
4 short java.lang.Short S
5 int java.lang.Integer I
6 long java.lang.Long J
7 float java.lang.Float F
8 double java.lang.Double D
9 void java.lang.Void V

注意:原始類型與對象類型的Class不一樣,類型縮寫在.class文件中用到。另外,class或interface的類型縮寫為L。

2 對象創(chuàng)建

英文:{@code Class} has no public constructor. Instead {@code Class} objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the {@code defineClass} method in the class loader.
中文:Class沒有公有構(gòu)造器函數(shù),虛擬機裝載類對象或被調(diào)用ClassLoader的defineClass方法時,Class對象實例被JAVA虛擬機自動構(gòu)造。

Class對象實例的獲取方式

  • 對象實例調(diào)用getClass方法
Thread thobj = new Thread();
Class clazz = thobj.getClass();
System.out.println(clazz.getName());

對任何對象類型的實例,調(diào)用getClass()函數(shù)可以獲取對象類型。

  • 類字面量.class方式
Class clazz = String.class;
System.out.println(clazz.getName());

類字面量,就是指用class關(guān)鍵字聲明的對象名稱,如public class Foo {}Foo就是這個類的類字面量。

  • 靜態(tài)函數(shù)forName
Class<?> clazz = Class.forName("java.lang.ArrayList");

請求參數(shù)為對象類型的全限定名稱,一般情況,不需要額外制定類加載器。

  • 泛型類型的獲取方式
Class<String> clazz = String.class
System.out.println(clazz.getName());

3 UML類圖

  • Class類聲明
public final class Class<T> implements java.io.Serializable, GenericDeclaration, Type,  AnnotatedElement {
  //主體代碼
}

聲明分析
1 final關(guān)鍵字,Class類不能被繼承;
2 實現(xiàn)AnnotatedElement接口,支持注解功能;
3 支持泛型,Class<T>聲明,實現(xiàn)GenericDeclaration,支持獲取泛型參數(shù)方法getTypeParameter;
4 實現(xiàn)Serializable接口,支持序列化。

  • Class類圖
    整理Class類實現(xiàn)的接口,依賴的類與接口。


    ClassUML類圖.png

4 類成員方法

4.1 構(gòu)造函數(shù)

函數(shù)聲明:private Class(ClassLoader loader)

  • 使用說明
    不能直接用new生成Class實例,也不提默認構(gòu)造函數(shù),直接由JVM在類裝載或ClassLoader調(diào)用defineClass是調(diào)用。

4.2 成員方法

4.2.1 forName方法

  • 方法作用
    靜態(tài)方法forName通過類的全限定名稱加載類對象,常用于反射功能模塊。兩個函數(shù)的區(qū)別主要區(qū)別在于第二個函數(shù)制定了一個類加載器,函數(shù)實現(xiàn)時增加對加載器的安全權(quán)限檢查。
  • 方法聲明
public static Class<?> forName(String name) throws ClassNotFoundException
public static Class<?> forName(String name, bool isInit, ClassLoader loader) throws ClassNotFoundException

方法拋出異常還有LinkageError與ExceptionInInitializerError。
forName底層調(diào)用靜態(tài)本地方法forName0函數(shù):

private static native Class<?> forName0(String name,  boolean isInit, ClassLoader loader, Caller<?> caller) throws ClassNotFoundException;

4.2.2 newInstance方法

  • 方法作用
    調(diào)用默認構(gòu)造函數(shù)生成對象實例。
  • 方法聲明
@CallerSensitive
public T newInstance() throws InstantiationException, IllegalAccessException
  • 函數(shù)分析

注解@CallerSensitive,表明函數(shù)執(zhí)行是否成功與調(diào)用者權(quán)限有關(guān),Class類代碼首先調(diào)用系統(tǒng)安全管理器檢查調(diào)用者對本類是否有訪問權(quán)限;
方法無參數(shù),就是說,只能生成具有默認無參構(gòu)造函數(shù)的類實例;若需要調(diào)用含參數(shù)列表的構(gòu)造函數(shù),需要通過反射技術(shù)調(diào)用Constructor類的newInstance方法;


4.2.3 isInstance方法

  • 方法作用
    判斷本類型是否繼承或?qū)崿F(xiàn)參數(shù)制定的類或接口。
  • 方法聲明
public native boolean isInstance(Object obj);

返回值說明

序號 this類型 obj說明 返回值
1 class obj是該類對象實例或子類型實例 true
2 array obj能執(zhí)行類型轉(zhuǎn)換為array對象 true
3 interface obj的類或上級類實現(xiàn)此接口 true
4 原始類型 任何情況 false

4.2.4 isAssignedFrom方法

  • 方法作用
    判斷本類型是否為參數(shù)clazz的相同,或者是其子類或?qū)崿F(xiàn)類。
  • 方法聲明
public native boolean isAssignedFrom(Class<?> clazz);

注意:與isInstance方法不同,這個參數(shù)是Class類型,而isInstance的參數(shù)是對象實例。

4.2.5 常用判斷方法

public native boolean isInterface(); #判斷是否為接口對象
public native boolean isArray(); #判斷是否為數(shù)組對象
public native boolean isPrimitive(); #判斷是否為原始類型,如byte, int等
public boolean isAnnotation(); #判斷是否為注解類型
public boolean isSynthetic(); #判斷是否為合成類,不是手動編寫的靜態(tài)類
public boolean isAnonymousClass(); #判斷是否為匿名類
public boolean isLocalClass(); #判斷是否為本地類
public boolean isMemberClass(); #判斷是否為成員類
public boolean isEnum(); #判斷是否為枚舉類型

4.2.6 字段操作方法

4.2.6.1 getField

  • 方法作用
    獲取類聲明的公有成員變量。
  • 方法聲明
@CallerSensitive
public Field getField(String name);

根據(jù)名稱參數(shù)name獲取類的同名字段,沒有名稱對應(yīng)的字段將拋出NoSuchFieldException。

4.2.6.2 getFields

  • 方法作用
    獲取類聲明的所有公有成員變量,返回Field數(shù)組,沒有成員變量返回空數(shù)組。
  • 方法聲明
@CallerSensitive
public Field[] getFields() throws SecurityException;

4.2.6.3 getDeclaredField方法

  • 方法作用
    獲取類聲明的同名成員變量,不管是公有還是私有,沒有此名稱成員變量拋出異常。
  • 方法申明
public Field getDeclaredField(String name);

4.2.6.4 getDeclaredFields方法

  • 方法作用
    獲取類聲明的所有成員變量,無論是公有還是私有,無成員變量返回空數(shù)組。
@CallerSensitive
public Field[] getDeclaredFields() throws SecurityException;

4.2.7 構(gòu)造器方法

4.2.7.1 getConstrucutor

  • 方法作用
    獲取與參數(shù)列表類型匹配的公有構(gòu)造函數(shù)。
  • 方法申明
@CallerSensitive
public Constructor<T> getConstructor(Class<?>... paramTypes) throws NoSuchMethodException, SecurityException

4.2.7.2 getDeclaredConstructor

  • 方法作用
    獲取與參數(shù)列表類型匹配的構(gòu)造函數(shù),不論公有私有。
  • 方法聲明
@CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... paramTypes) throws NoSuchMethodException, SecurityException

4.2.7.3 getConstructors

  • 方法作用
    獲取類聲明的所有公有構(gòu)造函數(shù),返回Constructor數(shù)組。
  • 方法聲明
@CallerSensitive
public Constructor[] getConstructors() throws SecurityException;

4.2.7.4 getDeclaredConstructors

  • 方法作用
    獲取類聲明的所有構(gòu)造函數(shù),不論公有私有,返回Constructor數(shù)組。
  • 方法聲明
@CallerSensitive
public Constructor[] getDeclaredConstructors() throws SecurityException;

4.2.8 成員方法函數(shù)

4.2.8.1 getMethod

  • 方法作用
    獲取與參數(shù)列表類型匹配的公有方法。
  • 方法申明
@CallerSensitive
public Method getMethod(Class<?>... paramTypes) throws NoSuchMethodException, SecurityException

4.2.8.2 getDeclaredMethod

  • 方法作用
    獲取與參數(shù)列表類型匹配的方法,不論公有私有。
  • 方法聲明
@CallerSensitive
public Method getDeclaredMethod(Class<?>... paramTypes) throws NoSuchMethodException, SecurityException

4.2.8.3 getMethods

  • 方法作用
    獲取類聲明的所有公有方法,返回Method數(shù)組。
  • 方法聲明
@CallerSensitive
public Method[] getMethods() throws SecurityException;

4.2.8.4 getDeclaredMethods

  • 方法作用
    獲取類聲明的所有方法,不論公有私有,返回Method數(shù)組。
  • 方法聲明
@CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException;

4.2.9 getModifiers方法

  • 方法作用
    獲取類聲明的訪問修飾符,如public, protected, final等。
  • 方法聲明
public native int getModifiers();

4.2.10 getInterfaces方法

  • 方法作用
    獲取類實現(xiàn)的接口列表數(shù)組,返回Class<?>數(shù)組, 沒有實現(xiàn)接口返回空數(shù)組。
  • 方法聲明
public Class<?>[] getInterfaces();

4.2.11 getClasses方法

  • 方法作用
    獲取類繼承或?qū)崿F(xiàn)接口的數(shù)組,返回Class<?>數(shù)組, 沒有集成與實現(xiàn)接口返回空數(shù)組。
  • 方法聲明
public Class<?> getClasses();

注意:getClasses方法包含getInterfaces方法返回的接口數(shù)組,排序與源代碼聲明順序一致。

4.2.12 getSuperclass方法

  • 方法作用
    獲取類的父類型,Class代表的類型可以是class / interface / 原始類型 / void。
  • 方法聲明
public native Class<? super T> getSuperclass();
  • 返回值說明
    如果this是原始類型,父類型返回null;如果this代表一個數(shù)組,父類型返回java.lang.Object。

4.2.13 getPackage方法

  • 方法作用
    返回類所在的包對象。
  • 方法聲明
public Package getPackage();

4.2.14 getComponentType方法

  • 方法作用
    獲取數(shù)組元素類型,如果this不是數(shù)組類型,返回null。
  • 方法聲明
public native Class<?> getComponentType()
  • 應(yīng)用示例
    數(shù)組String[],函數(shù)返回數(shù)組元素類型java.lang.String。

4.2.15 getName方法

  • 方法作用
    獲取this對象的全限定名稱。
  • 方法聲明
public String getName();
  • 應(yīng)用示例
  1. 對象類型,如String.class.getName(),返回名稱為java.lang.String;
  2. 原始類型,如byte.class.getName(),返回名稱與原始類型一樣,這里返回"byte";
  3. 數(shù)組類型,分兩種情況:1)原始類型數(shù)組,返回“前綴[ + 類型縮寫",如byte[5],返回字符串”[B“;2)對象數(shù)組,返回前綴[ + 類型全限定名稱”,如String[5], 返回[Ljava.lang.String;
  4. 多維數(shù)組,與數(shù)組類型格式一致,數(shù)組有幾維、就有幾個前綴[,如long[2][3][4][5],返回字符串“[[[[J”;

4.2.16 注解操作方法

Spring / MyBatis就是調(diào)用Class類的注解操作方法,解析BEAN對象等的注解配置的,研究框架得多了解下這幾個函數(shù)。

4.2.16.1 getAnnotation方法

  • 方法作用
    根據(jù)注解的類型獲取類聲明的注解對象。
  • 方法聲明
public <A extends Annotation> A getAnnotation(Class<A> annotationType);
  • 使用示例
@RestController("/message")
class MessageController {
    @RequestMapping(value="annotation")
    public String getAnnotation(){
        RestController obj =(RestController)this.getClass().getAnnotation(RestController.class);
        System.out.println(obj.value());
        return obj.value();
    }
}

4.2.16.2 getAnnotations方法

  • 方法作用
    獲取類聲明的所有注解對象,返回Annotation數(shù)組,沒有注解返回空數(shù)組。
  • 方法聲明
public Annotation[] getAnnotations();

4.2.16.3 isAnnotationPresent方法

  • 方法作用
    返回類是否聲明annotationType參數(shù)指定的注解。
  • 方法聲明
public boolean isAnnotationPresent(Annotation<? extends Annotation> annotationType) ;
  • 方法示例
@Deprecated
public class App{
    public static void main(String[] args){
        /* 判斷App類是否被Deprecated注解標識成Deprecated */
        boolean isOld = App.class.isAnnotationPresent(Deprecated.class);
    }
}

4.2.16.4 getAnnotationsByType方法

  • 方法作用
    根據(jù)注解類型annotationType獲取類聲明的所有注解,返回Annotion[]。
  • 方法聲明
public <A extends Annotation> A[] getAnnotationsByType(Class<A extends Annotation> annotationType)

4.3 其它函數(shù)

Class類的方法還有不少,尤其是要研究幾個內(nèi)部類的作用,如EnclosingMethodInfo、ReflectionData等,了解其緩存優(yōu)化等特點。

5 學(xué)習(xí)總結(jié)

Class類是反射技術(shù)的核心類

掌握forName方法使用,熟練使用構(gòu)造函數(shù)、成員變量、成員變量獲取函數(shù)

了解getSuperclass、getClasses與getInterfaces方法使用,動態(tài)代理過程常用

熟悉注解對象操作函數(shù),框架對象屬性配置經(jīng)常用到

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容