转贴来自:
http://www.ibm.com/developerworks/cn/java/j-arrays/#3数组反射
如果因为某种原因,您并不确定参数或对象是不是数组,您可以检索对象的
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<length; 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<length; 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; }
|