JAVA中的Class類

前言

Class類是一個看起來熟悉又看起來陌生的類,平時常常用到它,但卻從來沒有創建過它的實例對象,因爲它的構造函數是私有的,只有虛擬機才能夠創建它的對象,但是它絕對是一個核心類,以至於要學好java就必須要精通它,希望我的理解可以對你有所幫助。


Class類是什麼

(1)它是一個類,存在於java.lang包中,它的構造函數是私有的,由JVM(類加載器)創建Class對象,我們可以通過getClass()方法獲取到Class對象。

    /*
     * 私有構造函數,使得只有jvm可以創建該類的對象,這個私有構造函數還可以防止通過默認構造函數創建類對象
     */
    private Class(ClassLoader loader) {
        // 初始化final變量ClassLoader
        classLoader = loader;
    }

(2)Class對象,通過它我們可以拿到創建的類的屬性,方法等。


Class類的作用

(1)獲取類中屬性的類型
(2)獲取類中屬性的名稱
(3)獲取類的方法
(4)獲取類的基類等等
(5)綜合上述可以利用它完成反射

Class的主要方法

1.forName方法

輸入需要加載的類的全路徑名,得到類的Class對象

2.newInstance方法

  public T newInstance()
        throws InstantiationException, IllegalAccessException
    {
        if (System.getSecurityManager() != null) {
            checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
        }
        // NOTE: 下面的編碼可能不是嚴格符合當前的java內存模型
        // 尋找構造器
        if (cachedConstructor == null) {
            if (this == Class.class) {
                throw new IllegalAccessException(
                    "Can not call newInstance() on the Class for java.lang.Class"
                );
            }
            try {
                Class<?>[] empty = {};
               //獲取無參構造器,如果沒有就拋出異常,說明這個方法只適用於有無參構造函數的類
                final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
                // 設置構造器允許訪問
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<Void>() {
                        public Void run() {
                                c.setAccessible(true);
                                return null;
                            }
                        });
                cachedConstructor = c;
            } catch (NoSuchMethodException e) {
                throw (InstantiationException)
                    new InstantiationException(getName()).initCause(e);
            }
        }
        Constructor<T> tmpConstructor = cachedConstructor;
        // 安全檢查
        int modifiers = tmpConstructor.getModifiers();
        if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
            Class<?> caller = Reflection.getCallerClass();
            if (newInstanceCallerCache != caller) {
                Reflection.ensureMemberAccess(caller, this, null, modifiers);
                newInstanceCallerCache = caller;
            }
        }
        // 執行無參構造函數創建實例對象
        try {
            return tmpConstructor.newInstance((Object[])null);
        } catch (InvocationTargetException e) {
            Unsafe.getUnsafe().throwException(e.getTargetException());
            // Not reached
            return null;
        }
    }

3.isInstance(native方法)

用於判斷入參是否爲當前Class對象(子類)的實現類

public class TestInfo {

    static {
        System.out.println("我是誰");
    }

    public TestInfo(){
        System.out.println("我是構造函數");
    }
    public String test="測試屬性";
    public static void main(String[] args) {
        TestClass info=new TestClass();
        //返回結果是true因爲info是子類的對象
System.out.println(TestInfo.class.isInstance(info));
    }
    public static class TestClass extends TestInfo{

    }
}

4.getName、getTypeName、getCanonicalName、getSimpleName

    public static void main(String[] args) {
        System.out.println(TestClass.class.getTypeName());
        System.out.println(TestClass.class.getCanonicalName());
        System.out.println(TestClass.class.getSimpleName());
        System.out.println(TestClass.class.getName());
        System.out.println("-------------------------------------------------------");
        System.out.println(TestClass[].class.getTypeName());
        System.out.println(TestClass[].class.getCanonicalName());
        System.out.println(TestClass[].class.getSimpleName());
        System.out.println(TestClass[].class.getName());
    }

    public static abstract class TestClass<T extends TestInfo, String> extends TestInfo implements Aware, Comparable<Integer> {
        public abstract void test();
    }

輸出結果
com.hikvision.test.abc.TestInfo$TestClass
com.hikvision.test.abc.TestInfo.TestClass
TestClass
com.hikvision.test.abc.TestInfo$TestClass
-------------------------------------------------------
com.hikvision.test.abc.TestInfo$TestClass[]
com.hikvision.test.abc.TestInfo.TestClass[]
TestClass[]
[Lcom.hikvision.test.abc.TestInfo$TestClass;

5.getClassLoader

獲取當前類的類加載器

6.getTypeParameters

獲取泛型類中的泛型參數數組。

7.getSuperclass和getGenericSuperclass

都是獲取父類信息,但是後者會帶上泛型參數

8.getInterfaces和getGenericInterfaces

獲取當前Class對象實現的接口數組,但是後者會帶上接口的泛型參數,如

  public static void main(String[] args) {
        System.out.println(TestClass.class.getInterfaces()[1]);
    }

    public static abstract class TestClass<T extends TestInfo,String> extends TestInfo implements Aware,BeanFactory {
        public abstract void test();
    }

輸出結果
interface org.springframework.beans.factory.BeanFactory
java.lang.Comparable<java.lang.Integer>

9.isAssignableFrom(native方法)

這個方法比較反人類,括號裏的入參表示的是當前Class對象的父類或者是同一個對象時才成立。

//這樣返回的是false
System.out.println(TestClass.class.isAssignableFrom(TestInfo.class));

10.isInterface(native方法)

判斷是否爲接口

11.isArray(native方法)

是否爲數組

12.isPrimitive(native方法)

用於判斷這個Class對象是否爲基本類型,如int,byte,char等

13.isAnnotation

判斷這個Class對象是否爲註解

14.getComponentType

如果當前Class對象是數組,獲取數組中的元素類型

15.getModifiers

獲取屬性或方法前面的修飾詞對應的枚舉值

16.getDeclaringClass

獲取方法或屬性的歸屬類,或者獲取當前Class對象繼承於哪個類

17.getSimpleName

Class對象的類名

18.getClasses、getDeclaredClasses

(1)獲取Class對象中public修飾的內部類
(2)獲取Class對象中的內部類,繼承成員是不包含在內的

19.getFields、getField、getDeclaredFields

(1)獲取public修飾的屬性域
(2)根據輸入的屬性名查找對應的屬性域
(3)獲取Class對象中的屬性域

20.getMethods、getMethod、getDeclaredMethods

(1)獲取public修飾的方法
(2)根據輸入的方法名和入參類型,查找對應的方法
(3)獲取Class對象中的方法

21.getConstructors、getConstructor、getDeclaredConstructors

(1)獲取public修飾的構造函數
(2)根據輸入的方法名和入參類型,查找對應的構造函數
(3)獲取Class對象中的構造函數

最後

類裏面還有很多名稱類似的方法,可以根據上述說明推測出他們的功能,還有一些不常用的方法,這裏就不列舉了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章