RestTemplate get list of objects - Why use ParameterizedTypeReference instead of object array?

Sasidaran :

I am trying to get a list of objects using Spring RestTemplate. I am confused as to why choose ParameterizedTypeReference approach to get list of objects using restTemplate instead of just using Object[].class?

I have checked multiple answers suggesting to use ParameterizedTypeReference. But why can't I just use Object[].class? What limitations do I have?

I have checked this link (https://stackoverflow.com/a/49752261/6001027) where it says, I can use Object[] only for simple cases and have to got for ParameterizedTypeReference while handling complex json structures. Can someone explain me under what cases I cannot use Object[] approach?

ParameterizedTypeReference approach:

ResponseEntity<List<Rating>> responseEntity =
                restTemplate.exchange("http://localhost:8084/ratingsdata/user/" + userId,
                        HttpMethod.GET, null, new ParameterizedTypeReference<List<Rating>>() {
                        });
List<Rating> ratings = responseEntity.getBody();

Object[] approach:

List<Rating> ratings = Arrays.asList(restTemplate.getForObject("http://localhost:8084/ratingsdata/user/"+userId, Rating[].class));
Thomas Andolf :

The answer is simple, to keep type information during runtime.

A list can act as an array, but an array can't act like a list. Why what you are doing is working is because you are casting an array to a list, and as stated a list can act as an array so you are safe, this time.

But casting, in general, is bad practice.

When you are casting something you are taking a risk, you are basically forcing the compiler to "trust you" in what you are doing. So instead of the compiler telling you what is right or wrong, you are telling the compiler what is right and wrong and that is a risk, risk of breaking stuff. Hard, because if you are wrong during runtime, we might crash. Hard and uncontrollably.

There are many programmers with many opinions, but there is only one compiler with one opinion and we should trust it.

So back to the question, what does ParameterizedTypeReference<T>.class actually do?

If you look in its constructor you can see that it acts like a vessel for type information. By doing new ParameterizedTypeReference<List<Foo.class>> {}; you are instantiating an anonymous class while passing in a type. Then in the constructor it extract the type information from the type passed and stores it internally. Then at a later moment we can do getType() to get the type information so we can do a typesafe "casting" during runtime.

    final ParameterizedTypeReference<List<String>> typeRef = new ParameterizedTypeReference<>() {};
    final Type type = typeRef.getType();
    final String typeName = type.getTypeName();
    System.out.println(typeName);
    // will print "java.util.List<java.lang.String>"

This pattern is called "Super type tokens" and you can read more about it here Neal Gafter's blog - Super Type Tokens

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=306914&siteId=1