首页 > 解决方案 > List的Java反射数组

问题描述

我正在尝试实现一个可以将值初始化为任何类的对象的类。简单结构的初始化已经可以使用,但是我在尝试初始化 Lists ( List<String>[]) 数组时遇到了困难。

有没有办法找出数组的ParameterizedType而不是Class数组的getComponentType()

数组的创建:

if (cls.isArray()) {
  Class<?> c = cls.getComponentType();
  if (!c.isPrimitive()) {
    Array array = new Array(c, this.sizeArrays);

    for (int i = 0; i < this.sizeArrays; i++) {
      array.set(i, init(c, c, this.sizeArrays, this.sizeCollection, this.recursionCount, this.values, this.ignoredClass));
    }

    return array.getArray();
  }

类数组:

class Array<E> {
private final E[] objArray;
public final int length;

public Array(
    Class<E> dataType,
    int length
) {
  //noinspection unchecked
  this.objArray = (E[]) java.lang.reflect.Array.newInstance(dataType, length);
  this.length = length;
}

void set(
    int i,
    E e
) {
  objArray[i] = e;
}

E[] getArray() {
  return objArray;
}

}

创建列表:

if (Collection.class.isAssignableFrom(cls)) {
  ParameterizedType t = ((ParameterizedType) cls.getGenericSuperclass());
  if (type instanceof ParameterizedType) {
    ParameterizedType pt = (ParameterizedType) type;
    Collection collection;
    if (List.class.isAssignableFrom(cls)) {
      collection = new ArrayList(this.sizeCollection);
    } else if (Set.class.isAssignableFrom(cls)) {
      collection = new HashSet(this.sizeCollection);
    } else if (Queue.class.isAssignableFrom(cls)) {
      collection = new LinkedList();
    } else {
      collection = new ArrayList(this.sizeCollection);
    }
    for (int i = 0; i < this.sizeCollection; i++) {
      collection.add(init((Class<?>) pt.getActualTypeArguments()[0], pt.getActualTypeArguments()[0], this.sizeArrays, this.sizeCollection, this.recursionCount, this.values, this.ignoredClass));
    }

    return collection;
  }
}

标签: javaarrayslistgenericsreflection

解决方案


Type描述 aList<String>[]是 a ,而GenericArrayType不是 a ParameterizedType

下面的代码将说明这一点。代码会直接转换,因为我们知道字段类型,实际代码当然会instanceof在转换之前使用。

List<String>[] x;

public static void main(String[] args) throws Exception {
    Field field = Test.class.getDeclaredField("x");
    
    Class<?> fieldType = field.getType();
    System.out.println(fieldType);                    // class [Ljava.util.List;
    System.out.println(fieldType.isArray());          // true
    System.out.println(fieldType.getComponentType()); // interface java.util.List
    
    GenericArrayType arrayType = (GenericArrayType) field.getGenericType();
    ParameterizedType compType = (ParameterizedType) arrayType.getGenericComponentType();
    System.out.println(arrayType);             // java.util.List<java.lang.String>[]
    System.out.println(compType);              // java.util.List<java.lang.String>
    System.out.println(compType.getRawType()); // interface java.util.List
    for (Type argType : compType.getActualTypeArguments())
        System.out.println("  " + argType);    //   class java.lang.String
}

推荐阅读