23

I want to create a rest to communicate between server and client.

The constructor given below:

public class RestHelper<I, R> {
    public RestHelper(String url, I input, Class<R> output){
        ResponseEntity<R> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, output );
    }
}

For normal type, I can do:

RestHelper<User, Result> helper = new RestHelper<>(url, user, Result.class);

How can I pass a generic type, like:

ResultContainData<Boolean>

The code below is not working:

    ResultContainData<Boolean> result = new ResultContainData<>();
    RestHelper<User, ResultContainData<Boolean>> helper = new RestHelper<>(url, user, (Class<ResultContainData<Boolean>>) ((ParameterizedType) result.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);

I got a runtime error: cannot cast to ParameterizedType.

Michael
  • 425
  • 1
  • 4
  • 14
  • 1
    Instead of telling us it "is not working" it would probably be better to post the compiler error. I reckon the problem is with `ResultContainData.class`, right? – John Nov 18 '14 at 17:27
  • As @John wrote, there is no such thing as **ResultContainData.class**, try **ResultContainData.class**. – Grzesuav Nov 18 '14 at 17:30
  • yes, the compile error is cannot select Parameterized Type – Michael Nov 18 '14 at 17:31

2 Answers2

14

I got the solution.

ResultContainData<Boolean> result = new ResultContainData<>();
RestHelper<User, ResultContainData<Boolean>> helper = new RestHelper<>(url, user, (Class<ResultContainData<Boolean>>)result.getClass());

It's working for me. I am still looking for a better solution.

Michael
  • 425
  • 1
  • 4
  • 14
9

You can only learn the value of I and R by capturing them in a subclass definition - otherwise they are erased at runtime. Ex:

class MyStringRestHelper extends RestHelper<String, String> {

Then using something like my TypeTools you can resolve the values of I and R:

Class<?>[] typeArgs = TypeResolver.resolveRawArguments(RestHelper.class, MyStringRestHelper.class);
Class<?> i = typeArgs[0];
Class<?> r = typeArgs[1];
assert i == r == String.class;
Makyen
  • 31,849
  • 12
  • 86
  • 121
Jonathan
  • 5,027
  • 39
  • 48