天天看點

Java Reflection(十):數組

内容索引

<a href="http://ifeve.com/java-reflection-10-arrays/#javalangrefectionarray">java.lang.reflect.array</a>

<a href="http://ifeve.com/java-reflection-10-arrays/#creatingarrays">建立一個數組</a>

<a href="http://ifeve.com/java-reflection-10-arrays/#accessingarrays">通路一個數組</a>

<a href="http://ifeve.com/java-reflection-10-arrays/#obtainclassobjofarrays">擷取數組的class對象</a>

<a href="http://ifeve.com/java-reflection-10-arrays/#obtaincomponenttypeofarrays">擷取數組的成員類型</a>

利用反射機制來處理數組會有點棘手。尤其是當你想要獲得一個數組的class對象,比如int[]等等。本節會讨論通過反射機制建立數組和如何擷取數組的class對象。

<a></a>

java反射機制通過java.lang.reflect.array這個類來處理數組。不要把這個類與java集合套件(collections suite)中的java.util.arrays混淆,java.util.arrays是一個提供了周遊數組,将數組轉化為集合等工具方法的類。

java反射機制通過java.lang.reflect.array類來建立數組。下面是一個如何建立數組的例子:

<code>1</code>

<code>int</code><code>[] intarray = (</code><code>int</code><code>[]) array.newinstance(</code><code>int</code><code>.</code><code>class</code><code>, </code><code>3</code><code>);</code>

這個例子建立一個int類型的數組。array.newinstance()方法的第一個參數表示了我們要建立一個什麼類型的數組。第二個參數表示了這個數組的空間是多大。

通過java反射機制同樣可以通路數組中的元素。具體可以使用array.get(…)和array.set(…)方法來通路。下面是一個例子:

<code>2</code>

<code>3</code>

<code>array.set(intarray, </code><code>0</code><code>, </code><code>123</code><code>);</code>

<code>4</code>

<code>array.set(intarray, </code><code>1</code><code>, </code><code>456</code><code>);</code>

<code>5</code>

<code>array.set(intarray, </code><code>2</code><code>, </code><code>789</code><code>);</code>

<code>6</code>

<code>7</code>

<code>system.out.println(</code><code>"intarray[0] = "</code> <code>+ array.get(intarray, </code><code>0</code><code>));</code>

<code>8</code>

<code>system.out.println(</code><code>"intarray[1] = "</code> <code>+ array.get(intarray, </code><code>1</code><code>));</code>

<code>9</code>

<code>system.out.println(</code><code>"intarray[2] = "</code> <code>+ array.get(intarray, </code><code>2</code><code>));</code>

這個例子會輸出:

<code>intarray[</code><code>0</code><code>] = </code><code>123</code>

<code>intarray[</code><code>1</code><code>] = </code><code>456</code>

<code>intarray[</code><code>2</code><code>] = </code><code>789</code>

<code>class stringarrayclass = string[].</code><code>class</code><code>;</code>

如果使用class.forname()方法來擷取class對象則不是那麼簡單。比如你可以像這樣來獲得一個原生資料類型(primitive)int數組的class對象:

<code>class intarray = class.forname(</code><code>"[i"</code><code>);</code>

在jvm中字母i代表int類型,左邊的‘[’代表我想要的是一個int類型的數組,這個規則同樣适用于其他的原生資料類型。

對于普通對象類型的數組有一點細微的不同:

<code>class stringarrayclass = class.forname(</code><code>"[ljava.lang.string;"</code><code>);</code>

注意‘[l’的右邊是類名,類名的右邊是一個‘;’符号。這個的含義是一個指定類型的數組。

需要注意的是,你不能通過class.forname()方法擷取一個原生資料類型的class對象。下面這兩個例子都會報classnotfoundexception:

<code>class intclass1 = class.forname(</code><code>"i"</code><code>);</code>

<code>class intclass2 = class.forname(</code><code>"int"</code><code>);</code>

我通常會用下面這個方法來擷取普通對象以及原生對象的class對象:

<code>public</code> <code>class getclass(string classname){</code>

<code>  </code><code>if</code><code>(</code><code>"int"</code> <code>.equals(classname)) </code><code>return</code> <code>int</code> <code>.</code><code>class</code><code>;</code>

<code>  </code><code>if</code><code>(</code><code>"long"</code><code>.equals(classname)) </code><code>return</code> <code>long</code><code>.</code><code>class</code><code>;</code>

<code>  </code><code>...</code>

<code>  </code><code>return</code> <code>class.forname(classname);</code>

<code>}</code>

一旦你擷取了類型的class對象,你就有辦法輕松的擷取到它的數組的class對象,你可以通過指定的類型建立一個空的數組,然後通過這個空的數組來擷取數組的class對象。這樣做有點讨巧,不過很有效。如下例:

<code>class theclass = getclass(theclassname);</code>

<code>class stringarrayclass = array.newinstance(theclass, </code><code>0</code><code>).getclass();</code>

這是一個特别的方式來擷取指定類型的指定數組的class對象。無需使用類名或其他方式來擷取這個class對象。

為了確定class對象是不是代表一個數組,你可以使用class.isarray()方法來進行校驗:

<code>class stringarrayclass = array.newinstance(string.</code><code>class</code><code>, </code><code>0</code><code>).getclass();</code>

<code>system.out.println(</code><code>"is array: "</code> <code>+ stringarrayclass.isarray());</code>

一旦你擷取了一個數組的class對象,你就可以通過class.getcomponenttype()方法擷取這個數組的成員類型。成員類型就是數組存儲的資料類型。例如,數組int[]的成員類型就是一個class對象int.class。string[]的成員類型就是java.lang.string類的class對象。

下面是一個通路數組成員類型的例子:

<code>string[] strings = </code><code>new</code> <code>string[</code><code>3</code><code>];</code>

<code>class stringarrayclass = strings.getclass();</code>

<code>class stringarraycomponenttype = stringarrayclass.getcomponenttype();</code>

<code>system.out.println(stringarraycomponenttype);</code>

下面這個例子會列印“java.lang.string”代表這個數組的成員類型是字元串。