java:获取数组组件的类

Jas*_*n S 26 java arrays generics

如果我有

public <T> doSomething(T[] array)
{
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能T.classarray

如果我这样做array.getClass(),那就T[].class取而代之.

Sea*_*oyd 46

组件类型

用这个:

array.getClass().getComponentType()
Run Code Online (Sandbox Code Playgroud)

返回Class表示数组的组件类型.如果此类不表示此方法返回的数组类null.

参考:


安全/不安全的铸造

有没有一种方法可以从getComponentType()返回的类转换为Class而不会收到编译器警告?

采取这种方法:

public <T> void doSomething(final T[] array) throws Exception{
    final Class<? extends Object[]> arrayClass = array.getClass();
    final Class<?> componentType = arrayClass.getComponentType();
    final T newInstance = (T) componentType.newInstance();
}
Run Code Online (Sandbox Code Playgroud)

这是生成的字节码:

public void doSomething(java.lang.Object[] array) throws java.lang.Exception;
     0  aload_1 [array]
     1  invokevirtual java.lang.Object.getClass() : java.lang.Class [21]
     4  astore_2 [arrayClass]
     5  aload_2 [arrayClass]
     6  invokevirtual java.lang.Class.getComponentType() : java.lang.Class [25]
     9  astore_3 [componentType]
    10  aload_3 [componentType]
    11  invokevirtual java.lang.Class.newInstance() : java.lang.Object [30]
    14  astore 4 [newInstance]
    16  return
Run Code Online (Sandbox Code Playgroud)

如您所见,参数类型被删除为Object [],因此编译器无法知道T是什么.是的,编译器可以使用array.getClass().getComponentType(),但有时会失败,因为你可以做这样的事情:

Object[] arr = new String[] { "a", "b", "c" };
Integer[] integerArray = (Integer[]) arr;
doSomething(integerArray);
Run Code Online (Sandbox Code Playgroud)

(在这种情况下array.getClass().getComponentType()返回String.class,但T代表Integer.是的,这是合法的,不会生成编译器警告.)