Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
就像在非反射代码中一样,反射支持通过 java.lang.reflect.Array.newInstance()
动态创建任意类型和维度的数组的能力。考虑
,这是一个能够动态创建数组的基本解释器。将解析的语法如下:ArrayCreator
fully_qualified_class_name variable_name[] = { val1, val2, val3, ... }
假设 fully_qualified_class_name
表示具有构造函数的类,该构造函数具有单个 String
参数。数组的大小由提供的值的数量决定。以下示例将构造 fully_qualified_class_name
数组的实例,并使用 val1
,val2
等给出的实例填充其值。(此示例假设你熟悉 Class.getConstructor()
和 java.lang.reflect.Constructor.newInstance()
。有关 Constructor
的反射 API 的讨论,请参阅此路径的 Creating New Class Instances 部分。)
import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.Arrays; import static java.lang.System.out; public class ArrayCreator { private static String s = "java.math.BigInteger bi[] = { 123, 234, 345 }"; private static Pattern p = Pattern.compile("^\\s*(\\S+)\\s*\\w+\\[\\].*\\{\\s*([^}]+)\\s*\\}"); public static void main(String... args) { Matcher m = p.matcher(s); if (m.find()) { String cName = m.group(1); String[] cVals = m.group(2).split("[\\s,]+"); int n = cVals.length; try { Class<?> c = Class.forName(cName); Object o = Array.newInstance(c, n); for (int i = 0; i < n; i++) { String v = cVals[i]; Constructor ctor = c.getConstructor(String.class); Object val = ctor.newInstance(v); Array.set(o, i, val); } Object[] oo = (Object[])o; out.format("%s[] = %s%n", cName, Arrays.toString(oo)); // production code should handle these exceptions more gracefully } catch (ClassNotFoundException x) { x.printStackTrace(); } catch (NoSuchMethodException x) { x.printStackTrace(); } catch (IllegalAccessException x) { x.printStackTrace(); } catch (InstantiationException x) { x.printStackTrace(); } catch (InvocationTargetException x) { x.printStackTrace(); } } } }
$ java ArrayCreator java.math.BigInteger [] = [123, 234, 345]
上面的例子显示了一种可能需要通过反射创建数组的情况;即如果直到运行时才知道组件类型。在这种情况下,代码使用 Class.forName()
来获取所需组件类型的类,然后在设置相应的数组值之前,调用特定的构造函数来初始化数组的每个组件。