文档

Java™ 教程-Java Tutorials 中文版
创建新数组
Trail: The Reflection API
Lesson: Arrays and Enumerated Types
Section: Arrays

创建新数组

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

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

假设 fully_qualified_class_name 表示具有构造函数的类,该构造函数具有单个 String 参数。数组的大小由提供的值的数量决定。以下示例将构造 fully_qualified_class_name 数组的实例,并使用 val1val2 等给出的实例填充其值。(此示例假设你熟悉 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() 来获取所需组件类型的类,然后在设置相应的数组值之前,调用特定的构造函数来初始化数组的每个组件。


Previous page: Identifying Array Types
Next page: Getting and Setting Arrays and Their Components