java Class類

一.Java語言是先把Java源文件編譯成後綴爲class的字節碼文件,而後再經過ClassLoader機制把這些類文件加載到內存中,最後生成實例執行的,這是Java處理的基本機制,可是加載到內存中的數據的如何描述一個類的呢?好比在Dog.class文件中定義一個Dog類,那它在內存中是如何展示的呢?java

Java使用一個元類(MetaClass)來描述加載到內存中的類數據,這就是Class類,它是一個描述類的類對象,好比Dog.class文件加載到內存中後就會有一個class的實例對象描述之。由於是Class類是「類中類」,也就有預示着它有不少特殊的地方:編程

1.    無構造函數:Java中的類通常都有構造函數,用於建立實例對象,可是Class類卻沒有公共的構造方法,不能實例化,Class對象是在加載類時由Java虛擬機經過調用類加載器中的difineClass方法自動構造的,所以不能顯示的聲明一個class對象。框架

2.    基本的 Java 類型(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 也都對應一個 Class 對象,雖然8個基本類型在JVM中並非一個對象,它們通常存在於棧內存中,可是Class類仍然能夠描述它們,例如可使用int.class表示int類型的類對象。函數

虛擬機爲每種類型管理一個獨一無二的Class對象。也就是說,每一個類(型)都有一個Class對象。運行程序時,Java虛擬機(JVM)首先檢查是否所要加載的類對應的Class對象是否已經加載。若是沒有加載,JVM就會根據類名查找.class文件,並將其Class對象載入。其對象都是單例模式:一個Class的實例對象描述一個類,而且只描述一個類,反過來也成立。一個類只有一個Class實例對象,以下代碼返回的結果都爲true: 對象

下面咱們用java來看一看java語言自己是怎麼描述這個問題的。內存

public class Test {字符串

    public static void main(String[] args) {get

        People xiaoming = new People();原型

        System.out.println(xiaoming.getClass());//小明這個對象爲People類的一個對象虛擬機

        System.out.println(xiaoming.getClass().getClass());//People這個對象爲Class元類的一個對象

        System.out.println(xiaoming.getClass().getClass().getClass());//Class這個對象爲Class元類的一個對象

    }

}

class pyf.java.test.People

class java.lang.Class

class java.lang.Class

二.怎麼獲取類的元類型

那麼java中怎麼獲取一個類的元類呢?大概有下面這麼幾種方法:

1)類型.class (類屬性方式)

這種方式很直接,引用類型可使用該方式來獲取元類,基本類型也能經過該方式獲取元類

Class c1 = int.class;

Class c2 = InputStream.class;

2)實例.getClass()

這種方式是經過一個實例調用基類Object的方法

Person xiaoming = new Person();

Class<Person> cls = xiaoming.getClass();

Object的getClass方法原型以下:

public final native Class<?> getClass();

3)Class.forName(className)

這種方式,className指的是採用類的徹底限定名(完整的包名+類名,若是是內部類,則是包名+類名$內部類名),使用這種方式很靈活,由於參數是字符串,能夠結合配置文件來達到動態效果。

//假設類在pyf.java.demo包下,類名爲Person,則獲取方法以下

Class<?> cls = Class.forName("pyf.java.demo.Person");

Class.forName方式對於玩過jdbc的小夥伴應該很熟悉了,在加載jdbc驅動時就使用了該種方式

//DRIVER爲配置的jdbc驅動名稱

static {

    try {

        Class.forName(DRIVER);

    } catch (ClassNotFoundException e) {

        e.printStackTrace();

    }

}

使用場景

獲取元類的場景通常是在用到反射時,由於經過元類能拿到類自己的信息,如類的成員變量,構造方法,方法等,這爲動態化編程帶來了方便,這也是不少框架的基礎。得到了Class對象後,就能夠經過getAnnotations()得到註解,經過getMethods()得到方法,經過getConstructors()得到構造函數等,後續的反射代碼鋪平了道路。

3、總結:

1.萬物皆對象  2.抽象是具體的抽象,具體是抽象的具體  3.實例,類,元類的關係:具體,抽象,再抽象  4.元類的三種獲取方式 類型.class,實例.getClass,Class.forName(「類徹底限定名」)

相關文章
相關標籤/搜索