vviston
vviston

Reputation: 183

How to get Class object from parametrized List for input to new object declaration?

I rewrited this line of code:

JsonResponse<LoginResult> response = new JsonResponse<>(LoginResult.class);

to this:

JsonResponse<LoginResult[]> response = new JsonResponse<>(LoginResult[].class);

Because I wanted to pass the array of LoginResults.

But now I would like to rewrite it using ArrayList and of course I stuck in this:

JsonResponse<List<LoginResult>> response = new JsonResponse<List<LoginResult>>(List<LoginResult>.class);

I understand that I cannot get Class object from parametrized type. I read a lot of topics how to do that but I am not sure how to rewrite code in my situation, because I need the Class object as the input for JSonResponse constructor?

public class JsonResponse<T> extends JsonRequest {

    private Type type;

    public JsonResponse(Class<T> type) {
        this.type = type;
    }

    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    @SuppressWarnings("unchecked")
    public T getResult() {
        return (T) getAttribute(RESULT);
    }
}

Can you help me or give me some clue how solve this problem? Thank you!

Upvotes: 1

Views: 234

Answers (2)

Pierce Hanley
Pierce Hanley

Reputation: 126

You can find the JsonResponse's generic type parameter from any subclass, including an anonymous one.

public class JsonResponse<T> {

  private Type type;

  public JsonResponse() {
    Class<?> curClass = this.getClass();
    if (curClass == JsonResponse.class) {
      // not a subclass with a type parameter, so assume the response
      // is just an Object.
      type = Object.class;
    }
    else {
      // in case it's not a direct subclass, search upward for JsonResponse
      while (curClass.getSuperclass() != JsonResponse.class) {
        curClass = curClass.getSuperclass();
      }

      // get the generic type information for JsonResponse
      Type responseType = curClass.getGenericSuperclass();
      if (!(responseType instanceof ParameterizedType)) {
        throw new IllegalStateException(
          "JsonResponse type definition should have been parameterized.");
      }
      Type[] responseTypeParams =
          ((ParameterizedType) responseType).getActualTypeArguments();

      // get the only type parameter, <T>
      type = responseTypeParams[0];
    }
  }

  public Type getType() {
    return type;
  }
}

Now you can get the generic type information, as long as you actually instantiate it as an anonymous type:

// instantiate as an anonymous subclass (the "{}")
JsonResponse<?> response = new JsonResponse<List<String>>() {};
System.out.println(response.getType());
// outputs "java.util.List<java.lang.String>"

Upvotes: 1

Forketyfork
Forketyfork

Reputation: 7810

You can create a wrapper class for this list, something like:

public class LoginResultList {

    private List<LoginResult> loginResultList;

    // getters, setters etc...

}

Or you could inherit this container class from the ArrayList itself:

public class LoginResultList extends ArrayList<LoginResult> {}

Upvotes: 3

Related Questions