RestTemplate获取对象列表-为什么使用ParameterizedTypeReference而不是对象数组?

时间:2019-10-06 05:05:17

标签: java arrays spring arraylist resttemplate

我正在尝试使用Spring RestTemplate获取对象列表。我对为什么选择Para​​meterizedTypeReference方法使用restTemplate而不是仅使用Object []。class来获取对象列表感到困惑?

我检查了多个建议使用ParameterizedTypeReference的答案。但是为什么我不能只使用Object []。class?我有什么限制?

我已经检查了该链接(https://stackoverflow.com/a/49752261/6001027),其中说,我只能在简单情况下使用Object [],并且在处理复杂的json结构时必须使用ParameterizedTypeReference。有人可以在什么情况下不能使用Object []方法向我解释?

ParameterizedTypeReference方法:

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

对象[]方法:

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

1 个答案:

答案 0 :(得分:1)

答案很简单,可以在运行时保留类型信息。

列表可以充当数组,但是数组不能充当列表。之所以起作用,是因为将数组强制转换为列表,并且如上所述,列表可以充当数组,因此您很安全。

但是,通常来说,强制转换是不好的做法。

当您进行某些冒险时,您基本上是在强迫编译器“信任您”所做的事情。因此,您不是在告诉编译器是对是错,而是编译器告诉您是非对错,那是冒着破坏东西的风险。很难,因为如果在运行时出错,我们可能会崩溃。难以控制。

很多程序员有很多意见,但是只有一个编译器有一种意见,我们应该信任它。

那么回到问题上,ParameterizedTypeReference<T>.class的实际作用是什么?

如果查看其构造函数,您会发现它的作用类似于输入类型信息的容器。通过执行new ParameterizedTypeReference<List<Foo.class>> {};,您可以在传入类型时实例化一个匿名类。然后在构造函数中,从传递的类型中提取类型信息,并将其存储在内部。然后稍后,我们可以执行getType()来获取类型信息,以便在运行时进行类型安全的“广播”。

    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>"

此模式称为“超级类型令牌”,您可以在这里Neal Gafter's blog - Super Type Tokens

了解更多信息。