1. 程式人生 > >Java中如何獲得一個物件所對應的類及Class類的簡單理解

Java中如何獲得一個物件所對應的類及Class類的簡單理解

Java中如何獲得一個物件所對應的類及Class類的簡單理解

前言

在之前的學習中,所用的程式語言主要是Python,最近開始學習Java,熟悉Python的同學應該會知道在Python中有一個函式type(),通過這個函式可以非常方便地獲得一個變數的型別。那麼在Java中可不可以實現類似的功能呢?答案當然是可以的,一個比較簡單的方法就是利用Java中Class類來實現。

利用Class類的方法獲得一個物件所屬於的類

在這裡先給出一個例子:

List<Integer> listTest = new ArrayList<>();
System.
out.println(listTest.getClass().getName());

執行這段程式碼會輸出:

java.util.ArrayList

在這一段程式碼中,新建了一個ArrayList型別的例項listTest,在其後的一行程式碼中,用.getclass()方法獲得了listTest變數所屬於的類,並再用.getName()將這個類的名稱輸出出來。
同時,也可以用.toString()將完整的資訊打印出來:

System.out.println(listTest.getClass().toString());

結果為

class java.util.ArrayList

可以看到,用.getClass()方法可以很方便地獲得我們想要知道的物件變數所對應的類的名稱。
而以上是用於例項的獲取其類的型別的方法,與之類似的還有.class()方法,這個方法是針對類的,如:

System.out.println(ArrayList.class.getName());

輸出為:

java.util.ArrayList

關於Class類的一些理解

在上面的例子中,我們看到Class類有一些非常方便的應用,所以可以來簡單地瞭解以下Class類的內容。

java是一門比較純粹的面向物件的語言,在這樣一門語言裡,一切皆為物件。當然還是有著一些例外,比如從開發者的角度看靜態成員和普通資料型別就不屬於物件,靜態成員只屬於某個類,而不屬於物件,而普通資料型別是因為處於對效能的考慮,因為處理物件需要額外的系統開銷,所以顆將基本資料型別當作物件,就會給語言效能帶來負面影響,因此,在Java中基本資料型別是不作為物件來使用的,不過,在需要的時候可以通過方便的裝箱(boxing)與開箱(unboxing)來實現基本資料型別與物件之間的轉換。

當然,既然上面說了是從開發者的角度看,肯定對應著其它的角度,比如若在JVM的視角,會將所有的原始型別都當作物件處理,但是會為原始型別建立非常輕量級的物件,相比於其裝箱的包裝類的功能要少得多,但是會有很多優化。而對於靜態成員,就可以通過Class類來進行理解。

那麼,既然Java中,一切皆為物件,那麼在程式裡的類本身是不是物件呢?答案為是的,在Java中有這樣專門的一個類java.lang.Class,在程式中所寫的每一個類都既有著自己的物件,同時它自己本身也是Class類的物件。
在Java中,程式執行的期間,Java的執行時系統會始終為所有的物件維護一個被稱為執行時的型別標識,這個資訊跟蹤著每個物件所屬的類,虛擬機器則利用女性是型別資訊來選擇相應的方法執行,而儲存這些資訊的類就是Class類。而在之前我們的例子中的的.getClass()方法返回的就是這樣一個Class型別的例項,獲得Class類的方法主要有以下三種:

  1. Object類中的getClass()方法

  2. Class類中的forName()方法,例:Class cl = Class.forName(className); 輸入引數為雷鳴,獲得類名對應的Class物件。

  3. 如果T是任意的Java型別,則T.class返回匹配的類物件。

其中的1、3條即為本文開始時的兩個例子。

在這裡,需要注意的一點時,一個Class物件實際上上表示的是一個型別,而這個型別未必一定是一種類,如int不是類,但int.class是一個Class型別的物件。

Class類還有其它一些比較有用的地方,比如,虛擬機器為每個型別管理一個Class物件,因此,可以利用==運算子實現兩個類物件比較的操作,如:

if (e.getClass() == Employee.class)...

還有一個很有用的方法newInstance(),可以用來動態地建立一個類的例項。例如:

e.getClass().newInstance();

這個語句建立了一個與e具有相同類的型別的例項。newInstance方法呼叫預設的構造器(沒有引數的構造器)初始化新建立的物件。如果這個類沒有預設的構造器,就會丟擲一個異常。

forNamenewInstance配合使用,可以根據儲存在字串中的類名建立一個物件。

String s = "java.util.Random";
Object m = Class.forName(s).newInstance;

同時,還需要知道,Class類的建構函式為私有函式,即我們無法像定義普通類的例項那樣,用new的方法來構造Class的例項,若要獲得Class的例項可以通過上面介紹的三種方法。