创建新数组

原文: https://docs.oracle.com/javase/tutorial/reflect/special/arrayInstance.html

就像在非反射代码中一样,反射支持通过 java.lang.reflect.Array.newInstance() 动态创建任意类型和尺寸的数组的能力。考虑 ArrayCreator,这是一个能够动态创建数组的基本解释器。将解析的语法如下:

  1. fully_qualified_class_name variable_name[] =
  2. { val1, val2, val3, ... }

假设fully_qualified_class_name表示具有带有单个 String 参数的构造器的类。数组的大小由提供的值的数量决定。以下示例将构造fully_qualified_class_name数组的实例,并使用val1val2等给出的实例填充其值(此示例假定熟悉 Class.getConstructor()] java.lang.reflect.Constructor.newInstance() 。有关 Constructor 的反射 API 的讨论,请参阅此路径的创建新类实例部分。)

  1. import java.lang.reflect.Array;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.InvocationTargetException;
  4. import java.util.regex.Pattern;
  5. import java.util.regex.Matcher;
  6. import java.util.Arrays;
  7. import static java.lang.System.out;
  8. public class ArrayCreator {
  9. private static String s = "java.math.BigInteger bi[] = { 123, 234, 345 }";
  10. private static Pattern p = Pattern.compile("^\\s*(\\S+)\\s*\\w+\\[\\].*\\{\\s*([^}]+)\\s*\\}");
  11. public static void main(String... args) {
  12. Matcher m = p.matcher(s);
  13. if (m.find()) {
  14. String cName = m.group(1);
  15. String[] cVals = m.group(2).split("[\\s,]+");
  16. int n = cVals.length;
  17. try {
  18. Class<?> c = Class.forName(cName);
  19. Object o = Array.newInstance(c, n);
  20. for (int i = 0; i < n; i++) {
  21. String v = cVals[i];
  22. Constructor ctor = c.getConstructor(String.class);
  23. Object val = ctor.newInstance(v);
  24. Array.set(o, i, val);
  25. }
  26. Object[] oo = (Object[])o;
  27. out.format("%s[] = %s%n", cName, Arrays.toString(oo));
  28. // production code should handle these exceptions more gracefully
  29. } catch (ClassNotFoundException x) {
  30. x.printStackTrace();
  31. } catch (NoSuchMethodException x) {
  32. x.printStackTrace();
  33. } catch (IllegalAccessException x) {
  34. x.printStackTrace();
  35. } catch (InstantiationException x) {
  36. x.printStackTrace();
  37. } catch (InvocationTargetException x) {
  38. x.printStackTrace();
  39. }
  40. }
  41. }
  42. }
  1. $ java ArrayCreator
  2. java.math.BigInteger [] = [123, 234, 345]

上面的例子显示了一种可能需要通过反射创建数组的情况;即如果直到运行时才知道组件类型。在这种情况下,代码使用 Class.forName() 获取所需组件类型的类,然后在设置相应的数组值之前调用特定的构造器初始化数组的每个组件。