數組反射
如果因為某種原因,您并不确定參數或對象是不是數組,您可以檢索對象的 Class 對象并詢問它。 Class 類的 isArray()
方法将會告訴您。一旦您知道擁有了一個數組,您可以詢問 Class 的 getComponentType()
方法,您實際擁有的是什麼類型的數組。如果 isArray() 方法傳回 false,那麼 getComponentType()
方法傳回空。否則傳回元素的 Class 類型。如果數組是多元的,您可以遞歸調用 isArray() 。它将仍隻包含一個 component
類型。此外,您可以用在 java.lang.reflect 包裡找到的 Array 類的 getLength() 方法擷取數組的長度。
為了示範,清單 2-3 顯示了傳遞給 main() 方法的參數是 java.lang.String 對象的數組,其中數組長度由指令行參數的個數确定:
清單 2-3. 使用反射檢查數組類型和長度
public class ArrayReflection {
public static void main (String args[]) {
printType(args);
}
private static void printType (Object object) {
Class type = object.getClass();
if (type.isArray()) {
Class elementType = type.getComponentType();
System.out.println("Array of: " + elementType);
System.out.println(" Length: " + Array.getLength(object));
}
}
}
注意:如果 printType() 用于前面定義的 buttons 和 components 變量調用,每個都會表明數組是 java.awt.Button 類型。
如果不使用 isArray() 和 getComponentType() 方法,而且試圖列印數組的 Class 類型,您将獲得一個包含 [
,後面跟着一個字母和類名(如果是個基本資料類型就沒有類名)的字元串。例如,如果您試圖列印出上述 printType()
方法中的類型變量,您将獲得 class [Ljava.lang.String; 作為輸出。
除了詢問一個對象是不是數組以及是什麼類型的數組之外,您還可以在運作時用 java.lang.reflect.Array class 建立數組。這對于建立一般實用例程非常有用,這些例程執行數組任務,比如将大小加倍。(我們會立即回到那一點。)
要建立一個新數組,使用 Array 的 newInstance()
方法,它有兩種變化形式。對于一維數組您通常将使用較簡單版本,它的執行方式如語句 new type [length] 所示,并作為對象傳回數組:
public static Object newInstance(Class type, int length)
。例如,下面的代碼建立一個五個整數空間大小的數組:
int array[] = (int[])Array.newInstance(int.class, 5);
注意:要為基本資料類型指定 Class 對象,隻要在基本資料類型名末尾添加 .class 就可以了。您還可以使用包裝類中的 TYPE 變量,如 Integer.TYPE。
newInstance() 方法中的第二種變化形式要求維數被指定為整型數組: public static Object
newInstance(Class type,int dimensions [])
。在建立一個一維數組的最簡單的情況下,您将建立隻有一個元素的數組。換句話說,如果您要建立包含五個整數的相同數組,您需要建立一個單個元素 5
的數組并傳遞到 newInstance() 方法,而不是傳遞整數值 5。
int dimensions[] = {5};
int array[] = (int[])Array.newInstance(int.class, dimensions);
在您隻需要建立一個矩形數組的時候,您就可以将每個數組長度填充到這個 dimensions 數組中。例如,下面的代碼與建立一個 3 X 4 的整數數組等價。
int dimensions[] = {3, 4};
int array[][] = (int[][])Array.newInstance(int.class, dimensions);
但是,如果您需要建立一個非矩形數組,您将需要多次調用 newInstance()
方法。第一次調用将定義外部數組的長度,并獲得一個看上去很古怪的類參數([].class 适用于元素為 float
類型的數組)。每個後續調用将定義每個内部數組的長度。例如,下面示範了如何建立一個元素為 float
類型的數組,其内部數組的大小設定像一組保齡球瓶:第一排一個元素,第二排兩個,第三排三個,第四排四個。為了幫您将這種情況形象化,讓我們回顧早先在圖
2-4 展示的三角形數組。
float bowling[][] = (float[][])Array.newInstance(float[].class, 4);
for (int i=0; i<4; i++) {
bowling[i] = (float[])Array.newInstance(float.class, i+1);
}
一旦在運作時建立了數組,您還可以擷取和設定數組元素。不過通常不會這樣做,除非鍵盤上的方括号鍵失靈或者您在動态的程式設計環境(程式被建立時數組名
未知)中工作。 如表 2-2 所示, Array 類有一系列的 getter 和 setter
方法用來擷取和設定數組元素。使用什麼方法取決于您處理的數組類型。
表 2-2. 數組 getter 和 setter 方法
Getter 方法 Setter 方法
get(Object array, int index) set(Object array, int index, Object value)
getBoolean(Object array, int index) setBoolean(Object array, int index, boolean value)
getByte(Object array, int index) setByte(Object array, int index, byte value)
getChar(Object array, int index) setChar(Object array, int index, char value)
getDouble(Object array, int index) setDouble(Object array, int index, double value)
getFloat(Object array, int index) setFloat(Object array, int index, float value)
getInt(Object array, int index) setInt(Object array, int index, int value)
getLong(Object array, int index) setLong(Object array, int index, long value)
getShort(Object array, int index) setShort(Object array, int index, short value)
注意:您可以一直使用 get() 和 set() 方法。如果數組是一個基本資料類型數組, get() 方法的傳回值或 set() 方法的值參數将被包裝到用于基本資料類型的包裝類中,像裝着一個 int 數組的 Integer 類那樣。
清單 2-4 提供了一個如何建立、填充以及顯示數組資訊的完整示例。方括号隻在 main() 方法的聲明中使用。
清單 2-4. 使用反射建立、填充和顯示數組
import java.lang.reflect.Array;
import java.util.Random;
public class ArrayCreate {
public static void main (String args[]) {
Object array = Array.newInstance(int.class, 3);
printType(array);
fillArray(array);
displayArray(array);
}
private static void printType (Object object) {
Class type = object.getClass();
if (type.isArray()) {
Class elementType = type.getComponentType();
System.out.println("Array of: " + elementType);
System.out.println("Array size: " + Array.getLength(object));
}
}
private static void fillArray(Object array) {
int length = Array.getLength(array);
Random generator = new Random(System.currentTimeMillis());
for (int i=0; i
int random = generator.nextInt();
Array.setInt(array, i, random);
}
}
private static void displayArray(Object array) {
int length = Array.getLength(array);
for (int i=0; i
int value = Array.getInt(array, i);
System.out.println("Position: " + i +", value: " + value);
}
}
}
運作時,輸出将如下所示(盡管随機數會不同):
Array of: int
Array size: 3
Position: 0, value: -54541791
Position: 1, value: -972349058
Position: 2, value: 1224789416
讓我們傳回到早先的,建立一個将數組大小加倍的方法的示例。既然您知道如何擷取數組的類型,您可以建立一種方法用來将任意類型數組的大小加倍。這個方法確定我們能在擷取它的長度和類型之前得到數組。然後在複制原來的那組元素之前,它将新數組的大小加倍。
static Object doubleArray(Object original) {
Object returnValue = null;
Class type = original.getClass();
if (type.isArray()) {
int length = Array.getLength(original);
Class elementType = type.getComponentType();
returnValue = Array.newInstance(elementType, length*2);
System.arraycopy(original, 0, returnValue, 0, length);
}
return returnValue;
}
分享到:
2011-09-13 17:35
浏覽 1486
評論