1. 程式人生 > >【譯】2. Java反射——Class物件

【譯】2. Java反射——Class物件

===========================================================================================

在執行時,你可以用Java反射檢查Java類。當你使用反射時,你經常做的第一件事是檢查類。從類中你可以獲取下列相關資訊:

  • Class Name
  • Class Modifies (public, private, synchronized etc.)
  • Package Info
  • Superclass
  • Implemented Interfaces
  • Constructors
  • Methods
  • Fields
  • Annotations

  再加上很多和Java類相關的資訊。如果想要完整的列表,你應該去查閱java.lang.Class的JavaDoc。本篇文章將會簡要地涉及上述提到的資訊。一些主題也會在單獨的文章中做更詳細地研究。例如,本文將會告訴你怎麼獲取所有的方法或者一個特定的方法,而在其他單獨的文章中將會告訴你如何呼叫該方法,在多個方法擁有相同方法名的情況下如何找到和給定引數匹配的方法,通過反射呼叫一個方法時會丟擲什麼異常,如何識別出getter/setter方法等。這篇文章的目的主要是為了介紹Class物件以及你可以從中獲取哪些資訊。

===========================================================================================

  • The Class Object

  在你能對一個類做任何檢查之前,你需要獲取該類的java.lang.Class物件。Java中包括原始型別(int, long, float, etc.)和陣列在內的所有型別都有一個相關聯的Class物件。如果你在編譯的時候知道一個類的類名,你可以像下面這樣獲取一個Class物件:

Class myObjectClass = MyObject.class

  如果在編譯的時候你不知道類名,但是在執行時有一個字串形式的類名,你可以這樣做:

String className = ... //obtain class name as string at runtime Class class = Class.forName(className);

  當使用Class.forName()方法時,你必須提供完整有效的類名。這個類名包括完整的包名。例如,如果MyObject位於包com.jenkov.myapp中,那麼完整有效的類名為com.jenkov.myapp.MyObject。

  在執行時,如果該類在classpath中找不到,則Class.forName()方法會拋ClassNotFoundException。

===========================================================================================

  • Class Name

  從一個Class物件中,你可以得到兩種類名。像下面這樣通過getName()方法可以得到完成有效的類名(包括包名):

Class aClass = ... //obtain Class object. See prev. section
String className = aClass.getName();

     如果你想要獲取不包含包名的類名,你可以像下面這樣使用getSimpleName()方法獲取:

Class  aClass = ... //obtain Class object. See prev. section
String simpleClassName = aClass.getSimpleName();

===========================================================================================

  • Modifiers

  你可以通過Class物件訪問類的修飾符。類的修飾符即“public”、“private”、“static”等關鍵字。你可以像這樣獲取類的修飾符:

Class  aClass = ... //obtain Class object. See prev. section
int modifiers = aClass.getModifiers();

     修飾符被打包成一個int,每個修飾符是一個標誌位,可以被置位或清零。你可以用java.lang.reflect.Modifier中的這些方法來檢查修飾符:

Modifier.isAbstract(int modifiers)
Modifier.isFinal(int modifiers)
Modifier.isInterface(int modifiers)
Modifier.isNative(int modifiers)
Modifier.isPrivate(int modifiers)
Modifier.isProtected(int modifiers)
Modifier.isPublic(int modifiers)
Modifier.isStatic(int modifiers)
Modifier.isStrict(int modifiers)
Modifier.isSynchronized(int modifiers)
Modifier.isTransient(int modifiers)
Modifier.isVolatile(int modifiers)

===========================================================================================

  • Package Info

  你可以像這樣從Class物件中獲取包的相關資訊:

Class  aClass = ... //obtain Class object. See prev. section
Package package = aClass.getPackage();

     從Package物件中,你可以訪問像包名這樣的資訊。你也可以訪問在classpath中的JAR包中Manifest檔案所指定的該包的資訊。例如,你可以在Manifest檔案中指定包的版本號。你可以從java.lang.Package中閱讀更多和Package類相關的資訊。

===========================================================================================

  • Superclass

  你可以用Class物件訪問超類。如下:

Class superclass = aClass.getSuperclass();

     超類的Class物件和其他類的Class物件一樣,所以你也可以繼續在超類上用類的反射。

===========================================================================================

  • Implemented Interfaces

     可以得到一個給定類實現的介面的列表。如下:

Class  aClass = ... //obtain Class object. See prev. section
Class[] interfaces = aClass.getInterfaces();

     一個類可以實現多個介面。因此會返回一個Class型別的陣列。在Java反射機制中,介面也是由Class物件來表示的。

     注:只有被給定類特別宣告實現過的接口才會被返回。如果一個超類實現了一個介面,但是該類沒有特別宣告它已經實現了這個介面,那麼這個介面不會出現在返回的陣列中。即使該類實際上在它的超類中實現過該介面。
     要獲取一個給定類的完整的所實現介面的列表,你將不得不遞迴的去查詢該類以及它的超類。

===========================================================================================

  • Constructors

     你可以像這樣訪問一個類的建構函式:

Constructor[] constructors = aClass.getConstructors();

     建構函式在 Java反射——建構函式 中會有詳細介紹。

===========================================================================================

  • Methods

     你可以像這樣訪問一個類的方法:

Method[] method = aClass.getMethods();

  方法在 Java反射——方法 中會有詳細介紹。

===========================================================================================

  • Fields

     你可以像這樣訪問類的欄位(成員變數):

Field[] method = aClass.getFields();

     欄位在 Java反射——欄位 中會有詳細介紹。

===========================================================================================

  • Annotations

  你可以像這樣訪問類的註解:

Annotation[] annotations = aClass.getAnnotations();

     註解在 Java反射——註解 中會有詳細介紹。

 ========================================================================================

  • 目錄

  這是一個本教程到目前為止涵蓋的主題列表:     

(敬請期待下一篇翻譯)