以下是一个示例代码,需要获取运行时未知的数组的类名:
//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
的建议方法是什么?
答案 0 :(得分: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
答案 1 :(得分:0)
您不一定能确定values
中的值实际上是T
类型,因为类型擦除的数组会受到堆污染,您应该准备好处理ClassCastException
在你施展的那一刻。但是,您可以通过稍微复杂的Array.newInstance
调用来获取特定对象的数组类型:
Class<?> arrayClass = Array.newInstance(values[0].getClass(), 1).getClass();