1

通过反射使用数组有时会比较棘手。特别是需要获得一个特定类型数组的Class对象,如int[]等。本文将讨论如何通过反射创建数组和获得他们的Class对象。
注意:本文在阅读Eyal Lupu的博客"Two Side Notes About Arrays and Reflection" 后已更新,他的博客是本文第一个版本的评论。当前版本考虑了他的评论内容。

java.lang.reflect.Array

数组反射是通过类java.lang.reflect.Array实现的。不要把这个类与集合包的java.util.Arrays 混淆,java.util.Arrays 包含数组排序、转换成集合等。

Creating Arrays

通过反射创建数组是 java.lang.reflect.Array实现的。示例代码如下:

int[] intArray = (int[]) Array.newInstance(int.class, 3);

示例代码创建了一个int数组。Array.newInstance()方法的第一个参数int.class定义了数组每一个元素的类型。第二个参数定义数组的元素个数。

Accessing Arrays

可以通过反射访问数组元素。这是通过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的脚本语言时一个问题就是如何通过反射获得数组的Class对象。无反射代码如下:

Class stringArrayClass = String[].class;

做这些使用Class.forName() 并不是直接了当。例如,访问原始int数组类对象代码:

Class intArray = Class.forName("[I");

JVM使用小写l代表int。左边的[的意思是它是我有兴趣的int数组的类对象。其他基本类型也是按照这个模式工作。
对于其他类型对象,需要使用稍微不同的符号:

Class stringArrayClass = Class.forName("[Ljava.lang.String;");

注意:[L在类名的左侧,;在类名的右侧。这段代码的意思是给定类型的数组对象。
作为旁注,你不能使用Class.forName()获得基本类型的类对象。下面的两行代码都会抛出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.classClass对象。String[]数组的组合类型是java.lang.StringClass对象。
访问数组的组合类型的代码如下:

String[] strings = new String[3];
Class stringArrayClass = strings.getClass();
Class stringArrayComponentType = stringArrayClass.getComponentType();
System.out.println(stringArrayComponentType);

示例代码将输出"java.lang.String",这是String[]数组的组合类型。


团结
128 声望8 粉丝

诗酒趁年华