【Java基礎】RTTI和Java反射機制

一、RTTI

RTTI(Run-Time Type Information)指的是運行時類型信息,這讓你可以在程序運行時發現和使用類型信息。Java中讓我們在運行時識別對象和類的信息的方式主要有兩種。

  • 傳統的"RTTI",假定我們在編譯的時候就已經知道了所有的類型信息。
  • “反射”機制,允許我們在運行時候發現和使用類型信息。

二、RTTI使用背景

假設和我們定義了Shape, Square, Circle, Triangle.等類,並且後三者繼承自Shape。具體使用某個類的時候使用多態調用

Shape sp = new Circle();
sp = new Triangle();
sp = new Square();
一個圖形只要增加一個類,而具體調用的地方則不用修改。
現在有一個需求:把所有Triangle設置爲紅色。在只暴露了Shape的引用sp的情況下獲得sp具體的類型信息。這是就是RTTI的一個具體的需求,即在運行多態的好處是動態綁定調用方法,只有在執行的時候才知道sp綁定的是哪個具體子類的方法。這種方法的好處是代碼跟容易維護和擴展,因爲要增加時候發現和使用類型信息。
abstract class Shape{
    void draw(){
        System.out.println(this+".draw()");
    }

    abstract public String toString();
}

class  Circle extends Shape{

    @Override
    public String toString() {
        return "Circle";
    }
}

class  Square extends Shape{
    static {
        System.out.println("loading square......");
    }
    @Override
    public String toString() {
        return "Square";
    }
}

class  Triangle extends Shape{

    @Override
    public String toString() {
        return "Triangle";
    }
}

public class RTTI {
    public static void main(String[] args) {
        Shape sp = new Triangle();
       
    }
}

三、RTTI的核心

Java中支持RTTI工作的核心即是Class對象,類型信息是由Class對象所維護的。類是程序的一部分,每一個類都有一個Class對象(保存在.class) 文件之中,在使用一個類生成對象時,java虛擬機會使用類加載器加載Class對象(查找Class文件)。所以獲取RTTI就是獲取類的Class對象的引用。
常用的獲取RTTI的方法
  • 知道類的名稱
 Class<?> p = Class.forName("Inn");//有異常拋出
 Class<?> p = Inn.class;//字面常量
  • 知道類對象的引用
Class<?> p = sp.getClass();

四、反射:運行時的類信息

在使用傳統的RTTI時候有個限制,就是類型在編譯時候必須已知,這樣傳統的RTTI纔會識別。即在編譯時,編譯器必須知道所有要通過RTTI處理的類。
但是現在還有一個需求,假設你獲得了一個網絡程序的引用,你並不能在編譯期間獲得對象所屬的類。在分佈式環境中比較常見。
Java中支持反射機制的是Class類和java.lang.reflect類庫【Field、Method、Constructor】
通過運行時獲取Class對象,再通過Field、Method、Constructor獲取未知類的屬性、普通方法、構造器,從而對這個對象的類進行使用。
簡單來說 反射是和未知類型的對象打交道,使用未知對象提供的方法以及獲取其屬性。
傳統RTTI和反射機制的區別是
  • 對RTTI來說,在編譯期間打開和檢查.class文件
  • 對反射來說,在運行期間打開和檢查.class文件【本地獲取或者網絡獲取】

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