在Java中使用數(shù)組反射有時可能有點(diǎn)棘手。 特別是如果您需要獲取某個類型的數(shù)組的類對象,如int []等。本文將討論如何通過Java Reflection創(chuàng)建數(shù)組并獲取其類對象。
java.lang.reflect.Array中
通過Java處理數(shù)組反射是使用java.lang.reflect.Array類完成的。 請不要將此類與Java Collections套件中的java.util.Arrays類混淆,該類包含用于對數(shù)組進(jìn)行排序的實(shí)用程序方法,將它們轉(zhuǎn)換為集合等。
創(chuàng)建數(shù)組
通過Java創(chuàng)建數(shù)組反射是使用java.lang.reflect.Array類完成的。 下面是一個顯示如何創(chuàng)建數(shù)組的示例:
int[] intArray = (int[]) Array.newInstance(int.class, 3);
此代碼示例創(chuàng)建一個int數(shù)組。 給Array.newInstance()方法的第一個參數(shù)int.class告訴數(shù)組中每個元素應(yīng)該是什么類型。 第二個參數(shù)說明數(shù)組應(yīng)該有多少空間。
訪問數(shù)組
也可以使用Java Reflection來訪問數(shù)組的元素。 這是通過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));
獲取類對象的一個數(shù)組
我在Butterfly DI Container中實(shí)現(xiàn)腳本語言時碰到的一個問題是如何通過Java Reflection獲取數(shù)組的Class對象。 使用非反射代碼,你可以這樣做:
Class stringArrayClass = String[].class;
這樣做使用Class.forName()不是很簡單。 例如,你可以像這樣訪問基本的int數(shù)組類對象:
Class intArray = Class.forName("[I");
JVM通過字母I表示一個int。[左邊的意思是它是我感興趣的int數(shù)組的類。這也適用于所有其他基元。
對于需要使用稍微不同的記號的對象:
Class stringArrayClass = Class.forName("[Ljava.lang.String;");
注意[L在類名的左邊, 在右邊。 這意味著具有給定類型的對象數(shù)組。
作為一個方面說明,你不能使用Class.forName()來獲取原語的類對象。 下面的兩個例子都會導(dǎo)致一個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對象,就有了一個簡單的方法來獲得該類型的數(shù)組的Class。 解決方法或者你可能稱之為的解決方法是創(chuàng)建一個所需類型的空數(shù)組,并從該空數(shù)組中獲取類對象。 這是一個騙子,但它可以工作。
Class theClass = getClass(theClassName);
Class stringArrayClass = Array.newInstance(theClass, 0).getClass();
這提供了一個單一的,統(tǒng)一的方法來訪問任何類型的數(shù)組類。 沒有擺弄類名等
為了確保Class對象確實(shí)是一個數(shù)組,你可以調(diào)用Class.isArray()方法來檢查:
Class stringArrayClass = Array.newInstance(String.class, 0).getClass();
System.out.println("is array: " + stringArrayClass.isArray());
獲取數(shù)組的組件類型
一旦獲得數(shù)組的Class對象,就可以通過Class.getComponentType()方法訪問其組件類型。 組件類型是數(shù)組中項(xiàng)目的類型。 例如,一個int []數(shù)組的類型是int.class類對象。 String []數(shù)組的類型是java.lang.String類的對象。
這是訪問組件類型數(shù)組的一個例子:
String[] strings = new String[3];
Class stringArrayClass = strings.getClass();
Class stringArrayComponentType = stringArrayClass.getComponentType();
System.out.println(stringArrayComponentType);
這個例子將打印出字符串?dāng)?shù)組類型的文本“java.lang.String”。
實(shí)戰(zhàn)
package com.reflection.detail;
import java.lang.reflect.Array;
/**
* Created by Fant.J.
* 2018/2/7 16:50
*/
public class Reflection_Arrays {
public static void main(String[] args) throws ClassNotFoundException {
//用反射來定義一個int類型,3長度的數(shù)組
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));
//獲取類對象的類型
Class aClass = getClass("int");
//獲取類對象的一個數(shù)組
Class stringArrayClass = Array.newInstance(aClass, 0).getClass();
System.out.println("is array: " + stringArrayClass.isArray());
//獲取數(shù)組的組件類型
String[] strings = new String[3];
Class stringArrayClass2 = strings.getClass();
Class stringArrayComponentType = stringArrayClass2.getComponentType();
System.out.println(stringArrayComponentType);
}
static Class getClass(String className) throws ClassNotFoundException {
if("int" .equals(className)) {return int .class;}
if("long".equals(className)) {return long.class;}
return Class.forName(className);
}
}
intArray[0] = 123
intArray[1] = 456
intArray[2] = 789
is array: true
class java.lang.String
項(xiàng)目代碼:github鏈接