0

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

1 Answer 1

1

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
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.