Java反射-数组

时间:2020-01-09 14:21:09  来源:igfitidea点击:

有时在Java Reflection中使用数组可能会有些棘手。特别是如果需要为某种类型的数组(例如int []等)获取Class对象。本文将讨论如何创建数组以及如何通过Java Reflection获得它们的类对象。

java.lang.reflect.Array

使用java.lang.reflect.Array类可以通过Java Reflection处理数组。不要将此类与Java Collections套件中的java.util.Arrays类混淆,该类包含用于对数组进行排序,将其转换为集合等的实用方法。

创建数组

通过Java Reflection创建数组是通过使用java.lang.reflect.Array`类完成的。这是显示如何创建数组的示例:

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

此代码示例创建一个int数组。赋予Array.newInstance()方法的第一个参数int.class告诉数组中每个元素应该属于哪种类型。第二个参数说明数组应该有多少个空间。

访问数组

也可以使用Java Reflection访问数组的元素。这是通过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

获取数组的类对象

在Butterfly DI Container中实现脚本语言时,我遇到的问题之一是如何通过Java Reflection获取数组的Class对象。使用非反射代码,我们可以这样做:

Class stringArrayClass = String[].class;

使用Class.forName()做到这一点不是很简单。例如,我们可以像下面这样访问原始的int数组类对象:

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

JVM通过字母" I"表示一个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 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());

获取数组的组件类型

一旦获得了数组的Class对象,就可以通过Class.getComponentType()方法访问其组件类型。组件类型是数组中各项的类型。例如," int []"数组的组件类型是" int.class"" Class"对象。 String []数组的组件类型是java.lang.String` Class对象。

这是访问组件类型数组的示例:

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

本示例将打印出文本" java.lang.String",它是String数组的组件类型。