简体   繁体   中英

Java reflection arrays of List

I'm trying to implement a class that can initialize values into an object of any class. The initialization of simple structures is already functional, but I got stuck trying to initialize the array of Lists ( List<String>[] ).

Is there any way to find out the ParameterizedType and not just the Class of the array by getComponentType() ?

Creation of array:

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:

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;
}

}

Creating List:

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;
  }
}

The Type describing a List<String>[] is a GenericArrayType , not a ParameterizedType .

The following code will illustrate that. The code does direct casts, because we know the field type, real code would of course use instanceof before casting.

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM