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

java的rtti機制語法

編輯:關於JAVA

Java用Class對象實現自己的RTTI功能——即便我們要做的只是象造型那樣的一些工作。Class類也提供了其他大量方式,以方便我們使用RTTI。
首先必須獲得指向適當Class對象的的一個句柄。就象前例演示的那樣,一個辦法是用一個字串以及Class.forName()方法。這是非常方便的,因為不需要那種類型的一個對象來獲取Class句柄。然而,對於自己感興趣的類型,如果已有了它的一個對象,那麼為了取得Class句柄,可調用屬於Object根類一部分的一個方法:getClass()。它的作用是返回一個特定的Class句柄,用來表示對象的實際類型。Class提供了幾個有趣且較為有用的方法,從下例即可看出:
 

//: ToyTest.java
// Testing class Class

interface HasBatteries {}
interface Waterproof {}
interface ShootsThings {}
class Toy {
  // Comment out the following default
  // constructor to see 
  // NoSuchMethodError from (*1*)
  Toy() {} 
  Toy(int i) {} 
}

class FancyToy extends Toy 
    implements HasBatteries, 
      Waterproof, ShootsThings {
  FancyToy() { super(1); }
}

public class ToyTest {
  public static void main(String[] args) {
    Class c = null;
    try {
      c = Class.forName("FancyToy");
    } catch(ClassNotFoundException e) {}
    printInfo(c);
    Class[] faces = c.getInterfaces();
    for(int i = 0; i < faces.length; i++)
      printInfo(faces[i]);
    Class cy = c.getSuperclass();
    Object o = null;
    try {
      // Requires default constructor:
      o = cy.newInstance(); // (*1*)
    } catch(InstantiationException e) {}
      catch(IllegalAccessException e) {}
    printInfo(o.getClass());
  }
  static void printInfo(Class cc) {
    System.out.println(
      "Class name: " + cc.getName() +
      " is interface? [" +
      cc.isInterface() + "]");
  }
} ///:~

從中可以看出,class FancyToy相當復雜,因為它從Toy中繼承,並實現了HasBatteries,Waterproof以及ShootsThings的接口。在main()中創建了一個Class句柄,並用位於相應try塊內的forName()初始化成FancyToy。
Class.getInterfaces方法會返回Class對象的一個數組,用於表示包含在Class對象內的接口。
若有一個Class對象,也可以用getSuperclass()查詢該對象的直接基礎類是什麼。當然,這種做會返回一個Class句柄,可用它作進一步的查詢。這意味著在運行期的時候,完全有機會調查到對象的完整層次結構。
若從表面看,Class的newInstance()方法似乎是克隆(clone())一個對象的另一種手段。但兩者是有區別的。利用newInstance(),我們可在沒有現成對象供“克隆”的情況下新建一個對象。就象上面的程序演示的那樣,當時沒有Toy對象,只有cy——即y的Class對象的一個句柄。利用它可以實現“虛擬構建器”。換言之,我們表達:“盡管我不知道你的准確類型是什麼,但請你無論如何都正確地創建自己。”在上述例子中,cy只是一個Class句柄,編譯期間並不知道進一步的類型信息。一旦新建了一個實例後,可以得到Object句柄。但那個句柄指向一個Toy對象。當然,如果要將除Object能夠接收的其他任何消息發出去,首先必須進行一些調查研究,再進行造型。除此以外,用newInstance()創建的類必須有一個默認構建器。沒有辦法用newInstance()創建擁有非默認構建器的對象,所以在Java 1.0中可能存在一些限制。然而,Java 1.1的“反射”API(下一節討論)卻允許我們動態地使用類裡的任何構建器。
程序中的最後一個方法是printInfo(),它取得一個Class句柄,通過getName()獲得它的名字,並用interface()調查它是不是一個接口。
該程序的輸出如下:
 

Class name: FancyToy is interface? [false]
Class name: HasBatteries is interface? [true]
Class name: Waterproof is interface? [true]
Class name: ShootsThings is interface? [true]
Class name: Toy is interface? [false]

所以利用Class對象,我們幾乎能將一個對象的祖宗十八代都調查出來。

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