Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cannot select Parameterized Type

Tags:

java

spring

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.

like image 392
Michael Avatar asked Nov 18 '14 17:11

Michael


People also ask

What is parameterized type?

A parameterized type is an instantiation of a generic type with actual type arguments. A generic type is a reference type that has one or more type parameters. These type parameters are later replaced by type arguments when the generic type is instantiated (or declared ).

What Cannot be parameterized with a type using generics?

In Java, the java. util and java.

What is parameterized class in Java?

A parameterized class is a generic or skeleton class, which has formal parameters that will be replaced by one or more class-names or interface-names.

How do I restrict a generic type in Java?

Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class.


2 Answers

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.

like image 134
Michael Avatar answered Oct 21 '22 10:10

Michael


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;
like image 23
Jonathan Avatar answered Oct 21 '22 10:10

Jonathan