Java-API-Class類詳解、用法及泛化
阿新 • • 發佈:2018-12-09
Java-API-Class類詳解、用法及泛化
轉載宣告:
本文系轉載自以下文章:
- Java中Class類詳解、用法及泛化
作者: 老白講網際網路
轉載僅為方便學習檢視,一切權利屬於原作者,本人只是做了整理和排版,如果帶來不便請聯絡我刪除。
0x01 摘要
Java程式在執行時,JavaRuntime一直對所有的物件進行執行時型別標識,即所謂的RTTI。這項資訊紀錄了每個物件所屬的Class。虛擬機器通常使用執行時型別資訊選準正確方法去執行,用來儲存這些型別資訊的類是Class類
,他封裝了一個物件或介面執行時的狀態。當裝載類時,Class型別的物件會被自動建立。
0x02 什麼是Class類
- Class類也是類的一種,只是名字和
class
關鍵字高度相似。 - Class類的物件內容是建立的類的型別資訊。比如你建立一個shapes類物件例項,那麼,Java會生成一個內容是shapes的Class類的物件
- Class類的物件不能像普通類一樣,以 new shapes() 的方式建立,它的物件只能由JVM通過反射建立,因為這個類沒有public建構函式
- Class類的作用是執行時提供或獲得某個物件的型別資訊,這些資訊也可用於反射。
0x03 Class類原理
我們都知道所有的java類都是繼承了Object
這個類,其中有一個方法:getClass()
我們自己無法生成一個Class物件(建構函式為private),而這個Class類的物件是在當各類被載入時,由 JVM自動建立 ,或通過ClassLoader中的 defineClass 方法生成。我們生成的物件都會有個Field來記錄該物件所屬類在Class類的物件的所在位置。如下圖所示:
0x03 獲得一個Class類物件
- Class類的
forName
方法
public class shapes{}
Class obj= Class.forName("shapes");
- 使用物件的
getClass()
public class shapes{}
shapes s1=new shapes();
Class obj=s1.getClass();
//這個函式作用是獲取shapes類的父類的class物件
Class obj1=s1.getSuperclass();
- 使用類字面常量
Class obj=String.class;
Class obj1=int.class;
注意,使用第三種方法生成Class類物件時,不會使JVM自動載入該類(如String類)。而其他辦法會使得JVM初始化該類。
0x04 使用Class類的物件來生成目標類的例項
- 生成不精確的Oobject例項
獲取一個Class類的物件後,可以用newInstance()
函式來生成目標類的一個例項。然而,該函式並不能直接生成目標類的例項,只能生成Object類的例項
Class obj=Class.forName("shapes");
Object ShapesInstance=obj.newInstance();
- 使用泛型 Class引用生成帶型別的目標例項
Class<Shapes> obj=Shapes.class;
Shapes newShape=obj.newInstance();
- 因為有了型別限制,所以使用泛化Class語法的物件引用不能指向別的類。
Class obj1=int.class;
Class<Integer> obj2=int.class;
obj1=double.class;
//obj2=double.class; 這一行程式碼是非法的,obj2不能改指向別的類了
- 然而,有個靈活的用法,使得你可以用Class的物件指向基類的任何子類。
Class<? extends Number> obj = int.class;
obj = Number.class;
obj = double.class;
因此,以下語法生成的Class物件可以指向任何類。
Class<?> obj = int.class;
obj = double.class;
obj = Shapes.class;
最後一個奇怪的用法是,當你使用這種泛型語法來構建你手頭有的一個Class類的物件的基類物件時,必須採用以下的特殊語法
public class Shapes{}
class Round extends Shapes{}
Class<Round> rclass = Round.class;
Class<? super round> sclass= rclass.getSuperClass();
//Class<shapes> sclass=rclass.getSuperClass();