java之Class類詳解


測試中需要用到的代碼

InterfaceA代碼:

package jichu;

interface InterfaceA {
    String s1 = "this is s1 in InterfaceA";

    public String method1();
}

ClassA代碼:

package jichu;

public class ClassA {
    private String s1 = "this is s1 in ClassA";
    private String s2 = "this is s2 in ClassA";

    public String method1() {
        return "this is method1 in ClassA";
    }

    public String method2() {
        return "this is method2 in ClassA";
    }

    class Inner {
        private String s1 = "this is s1 in Inner";

        private String method1() {
            return "this is method1 in Inner";
        }
    }
}

ClassB代碼: 

package jichu;

public class ClassB {
}

 

Class

位置:java.lang包中

聲明public final class Class<T>implements java.io.Serializable, java.lang.reflect.GenericDeclaration,java.lang.reflect.Type,java.lang.reflect.AnnotatedElement

class 類有final 修飾,可知他不能被子類繼承;並且它實現了多個接口。

類型參數:T - 由此 Class 對象建模的類的類型。例如,String.class 的類型是 Class<String>。如果將被建模的類未知,則使用 Class<?>。

介紹:Class是一個java中的泛型類型。Class 類的實例表示正在運行的 Java 應用程序中的類和接口。枚舉是一種類,注釋是一種接口。每個數組屬於被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class 對象。基本的 Java 類型(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 也表示為 Class 對象。 

 

字段

    private static final int ANNOTATION= 0x00002000;
    private static final int ENUM      = 0x00004000;
    private static final int SYNTHETIC = 0x00001000;

 

構造器

    private Class() {}

構造器是私有的,可知不能通過new創建Class對象。

如何得到Class類的實例?

Class 對象是在加載類時由 Java 虛擬機以及通過調用類加載器中的 defineClass 方法自動構造的。

 

getName方法

public String getName()

以 String 的形式返回此 Class 對象所表示的實體(類、接口、數組類、基本類型或 void)名稱。

如果此類對象表示一個基本類型或 void,則返回的名字是一個與該基本類型或 void 所對應的 Java 語言關鍵字相同的String。

如果此類對象表示一個數組類,則名字的內部形式為:表示該數組嵌套深度的一個或多個 '[' 字符加元素類型名。元素類型名的編碼如下:

類型 編碼
boolean  Z
byte  B
char  C
class or interface  L  classname
double  D
float  F
int  I
long  J
short  S

 

 

toString方法

public String toString()

重寫了Object類的toString方法。

    public String toString() {
        return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
            + getName();
    }

如果是接口,則返回"interface "+getName();否則如果是基本類型,則返回getName();否則返回"class "+getName()。

 測試:

        Class c1 = ClassA.class;
        System.out.println(c1.toString());// class jichu.ClassA
        Class c2 = InterfaceA.class;
        System.out.println(c2.toString());// interface jichu.InterfaceA
        Class c3 = int.class;
        System.out.println(c3.toString());// int
        Class c4 = int[].class;
        System.out.println(c4.toString());// class [I
        Class c5 = void.class;
        System.out.println(c5.toString());// void
        Class c6 = (new ClassA().new Inner()).getClass();
        System.out.println(c6.toString());// class jichu.ClassA$Inner

 

獲取Class對象

forName(String className)

public static Class<?> forName(String className) 

返回與帶有給定字符串名的類或接口相關聯的 Class 對象。

注意:字符串名必須是全限定名。

測試:

        Class c = Class.forName("jichu.ClassA");
        System.out.println(c.toString());// class jichu.ClassA

forName(String name, boolean initialize,ClassLoader loader)

public static Class<?> forName(String name, boolean initialize,ClassLoader loader)throws ClassNotFoundException

上一個方法的重載方法,可以指定類名稱、加載時是否運行靜態區塊、指定類加載器。

類字面值

        Class c = ClassA.class;
        System.out.println(c1.toString());// class jichu.ClassA

Object中的getClass()

        ClassA c = new ClassA();
        System.out.println(c.getClass().toString());// class jichu.ClassA 

 

判斷型方法

public native boolean isInstance(Object obj);

判定指定的 Object 是否與此 Class 所表示的對象賦值兼容。此方法是 Java 語言 instanceof 運算符的動態等效方法。

public native boolean isArray();

判定此 Class 對象是否表示一個數組類。

public native boolean isPrimitive();

判定指定的 Class 對象是否表示一個基本類型。

public native boolean isInterface();

判定指定的 Class 對象是否表示一個接口類型。

public boolean isMemberClass();

當且僅當底層類是成員類時返回 true。

測試:

        Class c1 = ClassA.class;
        System.out.println(c1.isInstance(new ClassA()));// true
        System.out.println(c1.isInstance(new ClassB()));// false
        Class c2 = InterfaceA.class;
        System.out.println(c2.isInterface());// true
        Class c3 = int.class;
        System.out.println(c3.isPrimitive());// true
        Class c4 = int[].class;
        System.out.println(c4.isArray());// true
        Class c5 = void.class;
        System.out.println(c5.isPrimitive());// true
        Class c6 = (new ClassA().new Inner()).getClass();
        System.out.println(c6.isMemberClass());// true

 

獲取類型信息

獲取包名

public Package getPackage()

返回該類的包,如果存檔或基本代碼中沒有可用的包信息,則返回 null。

測試:

        Class c1 = ClassA.class;
        Class c2 = int.class;
        System.out.println(c1.getPackage());// package jichu
        System.out.println(c2.getPackage());// null

獲取超類

public native Class<? super T> getSuperclass();

此對象所表示的類的超類。

測試:

        Class c = ClassA.class;
        System.out.println(c.getSuperclass());// class java.lang.Object

獲取修飾符

public native int getModifiers();

表示該類修飾符的 int值。

測試:

        Class c1 = Class.forName("jichu.ClassA");
        Class c2 = Class.forName("jichu.InterfaceA");
        int[] arr = new int[] {};
        Class c3 = arr.getClass();
        System.out.println(c1.getModifiers());// 1
        System.out.println(c2.getModifiers());// 1536
        System.out.println(c3.getModifiers());// 1041

將返回的int值轉換成修飾符:

        System.out.println(Modifier.toString(c1.getModifiers()));// public
        System.out.println(Modifier.toString(c2.getModifiers()));// abstract interface
        System.out.println(Modifier.toString(c3.getModifiers()));// public abstract final

獲取非限定類名

public String getSimpleName();

返回源代碼中給出的底層類的簡稱。如果底層類是匿名的則返回一個空字符串。數組的簡稱即附帶 "[]" 的組件類型的簡稱。

測試:

        Class c1 = ClassA.class;
        Class c2 = InterfaceA.class;
        Class c3 = int.class;
        Class c4 = int[].class;
        Class c5 = void.class;
        System.out.println(c1.getSimpleName());// ClassA
        System.out.println(c2.getSimpleName());// InterfaceA
        System.out.println(c3.getSimpleName());// int
        System.out.println(c4.getSimpleName());// int[]
        System.out.println(c5.getSimpleName());// void

獲取全限定類名

public String getCanonicalName();

返回 Java Language Specification 中所定義的底層類的規范化名稱。如果底層類沒有規范化名稱(即如果底層類是一個組件類型沒有規范化名稱的本地類、匿名類或數組),則返回 null。

測試:

        Class c1 = ClassA.class;
        Class c2 = InterfaceA.class;
        Class c3 = int.class;
        Class c4 = int[].class;
        Class c5 = void.class;
        System.out.println(c1.getCanonicalName());//jichu.ClassA
        System.out.println(c2.getCanonicalName());// jichu.InterfaceA
        System.out.println(c3.getCanonicalName());// int
        System.out.println(c4.getCanonicalName());// int[]
        System.out.println(c5.getCanonicalName());// void

獲取所有成員變量

public Field[] getDeclaredFields() throws SecurityException

返回 Field 對象的一個數組,這些對象反映此 Class 對象所表示的類或接口所聲明的所有字段。包括公共、保護、默認(包)訪問和私有字段,但不包括繼承的字段。返回數組中的元素沒有排序,也沒有任何特定的順序。如果該類或接口不聲明任何字段,或者此 Class 對象表示一個基本類型、一個數組類或 void,則此方法返回一個長度為 0 的數組。 

測試:

        Class c = Class.forName("jichu.ClassA");
        Field[] arr = c.getDeclaredFields();
        StringBuffer s = new StringBuffer();
        for (Field f : arr) {
            s.append(Modifier.toString(f.getModifiers()) + " ");
            s.append(f.getType().getSimpleName() + " ");
            s.append(f.getName() + ";\n");
        }
        System.out.println(s.toString());

打印:

private String s1;
private String s2;

獲取指定名稱的成員變量

public Field getDeclaredField(String name)throws NoSuchFieldException, SecurityException

返回一個 Field 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明字段。name 參數是一個 String,它指定所需字段的簡稱。注意,此方法不反映數組類的 length 字段。

測試:

        Class c = Class.forName("jichu.ClassA");
        Field f = c.getDeclaredField("s2");
        StringBuffer s = new StringBuffer();
        s.append(Modifier.toString(f.getModifiers()) + " ");
        s.append(f.getType().getSimpleName() + " ");
        s.append(f.getName() + ";\n");
        System.out.println(s.toString());

打印:

private String s2;

獲取所有成員方法

public Method[] getDeclaredMethods() throws SecurityException

返回 Method 對象的一個數組,這些對象反映此 Class 對象表示的類或接口聲明的所有方法,包括公共、保護、默認(包)訪問和私有方法,但不包括繼承的方法。返回數組中的元素沒有排序,也沒有任何特定的順序。如果該類或接口不聲明任何方法,或者此 Class 對象表示一個基本類型、一個數組類或 void,則此方法返回一個長度為 0 的數組。

測試:

        Class c = Class.forName("jichu.ClassA");
        Method[] arr = c.getDeclaredMethods();
        StringBuffer s = new StringBuffer();
        for (Method m : arr) {
            s.append(Modifier.toString(m.getModifiers()) + " ");
            s.append(m.getReturnType().getSimpleName() + " ");
            s.append(m.getName() + ";\n");
        }
        System.out.println(s.toString());

打印:

public String method1;
public String method2;

獲取指定名稱的成員方法

public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

返回一個 Method 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明方法。name 參數是一個 String,它指定所需方法的簡稱,parameterTypes 參數是 Class 對象的一個數組,它按聲明順序標識該方法的形參類型。如果在某個類中聲明了帶有相同參數類型的多個方法,並且其中有一個方法的返回類型比其他方法的返回類型都特殊,則返回該方法;否則將從中任選一個方法。

測試:

        Class c = Class.forName("jichu.ClassA");
        Method m = c.getDeclaredMethod("method1");
        StringBuffer s = new StringBuffer();
        s.append(Modifier.toString(m.getModifiers()) + " ");
        s.append(m.getReturnType().getSimpleName() + " ");
        s.append(m.getName() + ";\n");
        System.out.println(s.toString());

打印:

public String method1;

 

創建實例

public T newInstance() throws InstantiationException, IllegalAccessException

創建此 Class 對象所表示的類的一個新實例。如同用一個帶有一個空參數列表的 new 表達式實例化該類。如果該類尚未初始化,則初始化這個類。 

測試:

        Class c = Class.forName("jichu.ClassA");
        ClassA o1 = (ClassA) c.newInstance();
        ClassA o2 = (ClassA) c.newInstance();
        System.out.println(o1.method1());// this is method1 in ClassA
        System.out.println(o1 == o2);// false

 


免責聲明!

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



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