383
阿裏雲
技術社區[雲棲]
Java Reflection(十):數組
內容索引
java.lang.reflect.Array
創建一個數組
訪問一個數組
獲取數組的Class對象
獲取數組的成員類型
利用反射機製來處理數組會有點棘手。尤其是當你想要獲得一個數組的Class對象,比如int[]等等。本節會討論通過反射機製創建數組和如何獲取數組的Class對象。
注意:在閱讀Eyal Lupu的博客文章“Two Side Notes About Arrays and Reflection”之後對本文的內容做了更新。目前這個版本參考了這篇博文裏麵的內容。
java.lang.reflect.Array
Java反射機製通過java.lang.reflect.Array這個類來處理數組。不要把這個類與Java集合套件(Collections suite)中的java.util.Arrays混淆,java.util.Arrays是一個提供了遍曆數組,將數組轉化為集合等工具方法的類。
創建一個數組
Java反射機製通過java.lang.reflect.Array類來創建數組。下麵是一個如何創建數組的例子:
1 |
int [] intArray = ( int []) Array.newInstance( int . class , 3 );
|
這個例子創建一個int類型的數組。Array.newInstance()方法的第一個參數表示了我們要創建一個什麼類型的數組。第二個參數表示了這個數組的空間是多大。
訪問一個數組
通過Java反射機製同樣可以訪問數組中的元素。具體可以使用Array.get(…)和Array.set(…)方法來訪問。下麵是一個例子:
1 |
int [] intArray = ( int []) Array.newInstance( int . class , 3 );
|
3 |
Array.set(intArray, 0 , 123 );
|
4 |
Array.set(intArray, 1 , 456 );
|
5 |
Array.set(intArray, 2 , 789 );
|
7 |
System.out.println( "intArray[0] = " + Array.get(intArray, 0 ));
|
8 |
System.out.println( "intArray[1] = " + Array.get(intArray, 1 ));
|
9 |
System.out.println( "intArray[2] = " + Array.get(intArray, 2 ));
|
這個例子會輸出:
獲取數組的Class對象
在我編寫Butterfly DI Container的腳本語言時,當我想通過反射獲取數組的Class對象時遇到了一點麻煩。如果不通過反射的話你可以這樣來獲取數組的Class對象:
1 |
Class stringArrayClass = String[]. class ;
|
如果使用Class.forName()方法來獲取Class對象則不是那麼簡單。比如你可以像這樣來獲得一個原生數據類型(primitive)int數組的Class對象:
1 |
Class intArray = Class.forName( "[I" );
|
在JVM中字母I代表int類型,左邊的‘[’代表我想要的是一個int類型的數組,這個規則同樣適用於其他的原生數據類型。
對於普通對象類型的數組有一點細微的不同:
1 |
Class stringArrayClass = Class.forName( "[Ljava.lang.String;" );
|
注意‘[L’的右邊是類名,類名的右邊是一個‘;’符號。這個的含義是一個指定類型的數組。
需要注意的是,你不能通過Class.forName()方法獲取一個原生數據類型的Class對象。下麵這兩個例子都會報ClassNotFoundException:
1 |
Class intClass1 = Class.forName( "I" );
|
2 |
Class intClass2 = Class.forName( "int" );
|
我通常會用下麵這個方法來獲取普通對象以及原生對象的Class對象:
1 |
public Class getClass(String className){
|
2 |
if ( "int" .equals(className)) return int . class ;
|
3 |
if ( "long" .equals(className)) return long . class ;
|
5 |
return Class.forName(className);
|
一旦你獲取了類型的Class對象,你就有辦法輕鬆的獲取到它的數組的Class對象,你可以通過指定的類型創建一個空的數組,然後通過這個空的數組來獲取數組的Class對象。這樣做有點討巧,不過很有效。如下例:
1 |
Class theClass = getClass(theClassName); |
2 |
Class stringArrayClass = Array.newInstance(theClass, 0 ).getClass();
|
這是一個特別的方式來獲取指定類型的指定數組的Class對象。無需使用類名或其他方式來獲取這個Class對象。
為了確保Class對象是不是代表一個數組,你可以使用Class.isArray()方法來進行校驗:
1 |
Class stringArrayClass = Array.newInstance(String. class , 0 ).getClass();
|
2 |
System.out.println( "is array: " + stringArrayClass.isArray());
|
獲取數組的成員類型
一旦你獲取了一個數組的Class對象,你就可以通過Class.getComponentType()方法獲取這個數組的成員類型。成員類型就是數組存儲的數據類型。例如,數組int[]的成員類型就是一個Class對象int.class。String[]的成員類型就是java.lang.String類的Class對象。
下麵是一個訪問數組成員類型的例子:
1 |
String[] strings = new String[ 3 ];
|
2 |
Class stringArrayClass = strings.getClass(); |
3 |
Class stringArrayComponentType = stringArrayClass.getComponentType(); |
4 |
System.out.println(stringArrayComponentType); |
下麵這個例子會打印“java.lang.String”代表這個數組的成員類型是字符串。
最後更新:2017-05-23 11:31:51