1

这是一个示例代码,需要获取运行时未知的数组的类名:

//for calling methods declared similar to
//  void method(String... values);
//For primitive type we have other overloads and the following 
//is generic for classes 

@SuppressWarnings("unchecked")
private static <T> void invokeVaridic(Method m, Object host, T... values) 
    throws IllegalAccessException, IllegalArgumentException, 
    InvocationTargetException, ClassNotFoundException{

    assert(values.length>0); //We assume all users passes at least one value
    Class<? extends T[]> c = (Class<? extends T[]>) 
            Class.forName("[L" + values[0].getClass().getName() + ";");
    m.invoke(host, Arrays.copyOf(values, values.length,c));
}

由于类型values实际上是类型擦除性质Object[],我不能将其传递给,m.invoke因为它需要String[]。但是,由于我强制用户传递至少一个值,因此我可以使用 的类型values[0]来构造一个新数组。

我不知道是什么T[].class

我想出了上面的代码,它取决于字节码中数组名称的解释,但它安全吗?建议的获取方式是什么T[].class

4

2 回答 2

4

values是类型T[]

Class<? extends T[]> arrayType = (Class<? extends T[]>) values.getClass();
Class<? extends T> component = (Class<? extends T>) values.getClass().getComponent();

/编辑

完整示例:

public class GenericArray {
    public static void main(String[] args) {
        foo("", "");
    }

    @SafeVarargs
    public static <T> void foo(T... args) {
        Class<? extends T[]> array = (Class<? extends T[]>) args.getClass();
        Class<? extends T> component = (Class<? extends T>) array.getComponentType();
        System.out.println(array);
        System.out.println(component);
    }
}

使用 JDK 1.7.0_25 打印以下内容

class [Ljava.lang.String;
class java.lang.String
于 2013-07-31T06:05:39.853 回答
0

您不一定能确定 in 中的值values实际上是 type T,因为类型擦除的数组会受到堆污染,您应该准备好在您转换时处理 a ClassCastException。但是,您可以通过稍微复杂的调用来获取特定对象的数组类型Array.newInstance

Class<?> arrayClass = Array.newInstance(values[0].getClass(), 1).getClass();
于 2013-07-31T06:06:33.870 回答