程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java的rtti中class對象

java的rtti中class對象

編輯:關於JAVA

為理解RTTI在Java裡如何工作,首先必須了解類型信息在運行期是如何表示的。這時要用到一個名為“Class對象”的特殊形式的對象,其中包含了與類有關的信息(有時也把它叫作“元類”)。事實上,我們要用Class對象創建屬於某個類的全部“常規”或“普通”對象。
對於作為程序一部分的每個類,它們都有一個Class對象。換言之,每次寫一個新類時,同時也會創建一個Class對象(更恰當地說,是保存在一個完全同名的.class文件中)。在運行期,一旦我們想生成那個類的一個對象,用於執行程序的Java虛擬機(JVM)首先就會檢查那個類型的Class對象是否已經載入。若尚未載入,JVM就會查找同名的.class文件,並將其載入。所以Java程序啟動時並不是完全載入的,這一點與許多傳統語言都不同。
一旦那個類型的Class對象進入內存,就用它創建那一類型的所有對象。
若這種說法多少讓你產生了一點兒迷惑,或者並沒有真正理解它,下面這個示范程序或許能提供進一步的幫助:
 

//: SweetShop.java
// Examination of the way the class loader works

class Candy {
  static {
    System.out.println("Loading Candy");
  }
}

class Gum {
  static {
    System.out.println("Loading Gum");
  }
}

class Cookie {
  static {
    System.out.println("Loading Cookie");
  }
}

public class SweetShop {
  public static void main(String[] args) {
    System.out.println("inside main");
    new Candy();
    System.out.println("After creating Candy");
    try {
      Class.forName("Gum");
    } catch(ClassNotFoundException e) {
      e.printStackTrace();
    }
    System.out.println(
      "After Class.forName(\"Gum\")");
    new Cookie();
    System.out.println("After creating Cookie");
  }
} ///:~

對每個類來說(Candy,Gum和Cookie),它們都有一個static從句,用於在類首次載入時執行。相應的信息會打印出來,告訴我們載入是什麼時候進行的。在main()中,對象的創建代碼位於打印語句之間,以便偵測載入時間。
特別有趣的一行是:
Class.forName("Gum");
該方法是Class(即全部Class所從屬的)的一個static成員。而Class對象和其他任何對象都是類似的,所以能夠獲取和控制它的一個句柄(裝載模塊就是干這件事的)。為獲得Class的一個句柄,一個辦法是使用forName()。它的作用是取得包含了目標類文本名字的一個String(注意拼寫和大小寫)。最後返回的是一個Class句柄。
該程序在某個JVM中的輸出如下:
 

inside main
Loading Candy
After creating Candy
Loading Gum
After Class.forName("Gum")
Loading Cookie
After creating Cookie

可以看到,每個Class只有在它需要的時候才會載入,而static初始化工作是在類載入時執行的。
非常有趣的是,另一個JVM的輸出變成了另一個樣子:
 

Loading Candy
Loading Cookie
inside main
After creating Candy
Loading Gum
After Class.forName("Gum")
After creating Cookie

看來JVM通過檢查main()中的代碼,已經預測到了對Candy和Cookie的需要,但卻看不到Gum,因為它是通過對forName()的一個調用創建的,而不是通過更典型的new調用。盡管這個JVM也達到了我們希望的效果,因為確實會在我們需要之前載入那些類,但卻不能肯定這兒展示的行為百分之百正確。

1. 類標記
在Java 1.1中,可以采用第二種方式來產生Class對象的句柄:使用“類標記”。對上述程序來說,看起來就象下面這樣:
Gum.class;
這樣做不僅更加簡單,而且更安全,因為它會在編譯期間得到檢查。由於它取消了對方法調用的需要,所以執行的效率也會更高。
類標記不僅可以應用於普通類,也可以應用於接口、數組以及基本數據類型。除此以外,針對每種基本數據類型的封裝器類,它還存在一個名為TYPE的標准字段。TYPE字段的作用是為相關的基本數據類型產生Class對象的一個句柄,如下所示:

……等價於……
 

... is equivalent to ...
 

boolean.class
 

Boolean.TYPE
 

char.class
 

Character.TYPE
 

byte.class
 

Byte.TYPE
 

short.class
 

Short.TYPE
 

int.class
 

Integer.TYPE
 

long.class
 

Long.TYPE
 

float.class
 

Float.TYPE
 

double.class
 

Double.TYPE
 

void.class
 

Void.TYPE
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved