【譯】10. Java反射——陣列
=====================================================================================
用Java反射來處理陣列有時候是技巧性很強的。特別是如果你需要獲取一個給定型別的陣列的Class物件,像int[ ]等。本文將講述怎麼用Java反射來建立陣列和獲取陣列的Class物件。
下面是所涵蓋的主題列表:
- java.lang.reflect.Array
- Creating Arrays
- Accessing Arrays
- Obtaining the Class Object of an Array
- Obtaining the Component Type of an Array
=====================================================================================
- java.lang.reflect.Array
通過Java反射來處理陣列需要用到java.lang.reflect.Array類。不要和Java集合中的java.util.Arrays類搞混淆了,它包含一些工具方法,像給陣列排序、將陣列轉換成集合等。
=====================================================================================
- Creating Arrays
通過Java反射來建立陣列需要用到java.lang.reflect.Array類。下面的這個例子中會展示如何去建立一個數組:
int[] intArray = (int[]) Array.newInstance(int.class, 3);
這段程式碼示例建立了一個int型的陣列。Array.newInstance( )方法的第一個引數int.class指定了陣列中的每個元素應該是什麼型別。第二個引數聲明瞭該陣列應該為多少個元素開闢空間。
=====================================================================================
- Accessing Arrays
也可以通過Java反射來訪問陣列中的元素。這是通過Array.get(…)和Array.set(…)方法做到的。下面是一個例子:
int[] intArray = (int[]) Array.newInstance(int.class, 3); Array.set(intArray, 0, 123); Array.set(intArray, 1, 456); Array.set(intArray, 2, 789); System.out.println("intArray[0] = " + Array.get(intArray, 0)); System.out.println("intArray[1] = " + Array.get(intArray, 1)); System.out.println("intArray[2] = " + Array.get(intArray, 2));
這段程式碼示例輸出如下:
intArray[0] = 123 intArray[1] = 456 intArray[2] = 789
=====================================================================================
- Obtaining the Class Object of an Array
我在Butterfly DI Container專案中開發指令碼語言時遇到一個問題,如何通過Java反射獲得陣列的Class物件。不用反射你可以這樣做:
Class stringArrayClass = String[].class;
對陣列用Class.forName()不是很直觀。例如,你可以像這樣訪問基本型別陣列的Class物件:
Class intArray = Class.forName("[I");
JVM中用字母I代表int。在左邊加上[(左中括號)表示我比較感興趣的int陣列的類。這對所有其他的基本型別同樣有效。
對於物件,你需要用一個稍微不同的符號:
Class stringArrayClass = Class.forName("[Ljava.lang.String;");
注意類名左邊的[L和右邊的分號(;)。這表示一個你指定型別的物件的陣列。
附註,你不能用Class.forName()獲取基本型別的Class物件。下面的例子都會導致ClassNotFoundException:
Class intClass1 = Class.forName("I");
Class intClass2 = Class.forName("int");
我通常像這樣做來獲取基本型別和物件的型別名:
public Class getClass(String className){ if("int" .equals(className)) return int .class; if("long".equals(className)) return long.class; ... return Class.forName(className); }
一旦你獲取了一種型別的Class物件,你也可以很簡單的獲取一個數組型別的Class物件。方案,或者你叫它變通措施,是先建立一個你期望的型別的空陣列,然後從這個空陣列獲取它的Class物件。這感覺有作弊的嫌疑,但是很有效。下面是它看起來的樣子:
Class theClass = getClass(theClassName);
Class stringArrayClass = Array.newInstance(theClass, 0).getClass();
這代表一個單一的、統一的訪問任何類型別的陣列。沒有擺弄類名等。
為了確認該Class物件的確是一個數組,你可以呼叫Class.isArray()來檢查:
Class stringArrayClass = Array.newInstance(String.class, 0).getClass(); System.out.println("is array: " + stringArrayClass.isArray());
=====================================================================================
- Obtaining the Component Type of an Array
一旦你獲取了陣列的Class物件,你可以通過Class.getComponentType()方法訪問它的元素型別。元素型別是陣列中元素的型別。例如,int[ ]陣列的元素型別是int.class的Class物件。String[ ]陣列的元素型別是java.lang.String的Class物件。
下面是一個訪問陣列元素型別的例子:
String[] strings = new String[3]; Class stringArrayClass = strings.getClass(); Class stringArrayComponentType = stringArrayClass.getComponentType(); System.out.println(stringArrayComponentType);
這個例子將會輸出String陣列的元素型別"java.lang.String"。
========================================================================================
- 目錄
這是一個本教程到目前為止涵蓋的主題列表:
(敬請期待下一篇翻譯)