Kalobasov Kalobasov - 7 months ago 9
Java Question

How to call parametrized method in Java?

I have such a method:

private static <T extends HomerMessage> HomerMessage postRequest(String path, HomerMessage json) throws IOException, HomerDoh
{
RequestBody body = RequestBody.create(JSON, toJson(json));
Request request = new Request.Builder().url("http://" + path).post(body).build();

String response = new OkHttpClient().newCall(request).execute().body().string();
System.out.println(response);
JsonNode responseNode = new ObjectMapper().readValue(response, JsonNode.class);
if(!"200".equals(responseNode.get("status")))
{
throw readData(response, new TypeReference<HomerDoh>() {});
}
return readData(response, new TypeReference<T>() {});
}

private static <T> T readData(String is, TypeReference<T> ref) throws IOException
{
return mapper.readValue(is, ref);
}


All works fine, but I could not figure out how to call it...
I have tried:

AuthResponse ar = HomerClient.postRequest(url + "/api/v1/session", auth);


The last expression does not compile.

How to call parametrized method in Java?

AuthResponse extends HomerMessage

Answer

Your code doesn't compile because it's not returning an AuthResponse: it is returning a HomerMessage.

You can make the return type AuthResponse if you change the return type of the method to:

private static <T extends HomerMessage> T postRequest(
    String path, HomerMessage json, TypeReference<T> typeRef)
        throws IOException, HomerDoh

which is the return type of your only normally-completing code path.


As noted by @SLaks, you can't use TypeReference with generics:

new TypeReference<T>() {}

Because of erasure, this will be equivalent at runtime to:

new TypeReference<Object>() {}

which is almost certainly not what you want - otherwise you could just have used that, and not had an issue calling the generic method in the first place.

You need to actually pass in the concrete TypeReference as a parameter:

private static <T extends HomerMessage> T postRequest(
    String path, HomerMessage json, TypeReference<T> typeRef)
        throws IOException, HomerDoh

then you can call this simply as:

AuthResponse response = postRequest(
    url + "/api/v1/session", auth,
    new TypeReference<AuthResponse>() {});

and the type T is inferred from the third parameter.