RestTemplate 获取对象列表 - 为什么使用 ParameterizedTypeReference 而不是对象数组?
RestTemplate get list of objects - Why use ParameterizedTypeReference instead of object array?
我正在尝试使用 Spring RestTemplate 获取对象列表。我很困惑为什么选择 ParameterizedTypeReference 方法来使用 restTemplate 而不是仅使用 Object[].class?
来获取对象列表
我检查了多个建议使用 ParameterizedTypeReference 的答案。但为什么我不能只使用 Object[].class?我有什么限制?
我已经检查了这个 link () 它说,我只能将 Object[] 用于简单的情况,并且在处理复杂的 json 结构时必须获取 ParameterizedTypeReference .有人可以解释一下在什么情况下我不能使用 Object[] 方法吗?
参数化类型引用方式:
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));
答案很简单,在运行时保留类型信息。
列表可以充当数组,但数组不能充当列表。为什么你正在做的事情是有效的,因为你正在将一个数组转换为一个列表,并且如上所述,一个列表可以充当一个数组,所以你这次是安全的。
但总的来说,铸造是一种不好的做法。
当你投射一些东西时,你是在冒险,你基本上是在强迫编译器"trust you"做你正在做的事情。因此,不是编译器告诉你什么是对的或错的,而是你告诉编译器什么是对的和错的,这是一种风险,破坏东西的风险。很难,因为 如果你在运行时出错,我们可能会崩溃。难以控制。
有很多程序员有很多意见,但只有一个编译器,一个意见,我们应该相信它。
回到问题,ParameterizedTypeReference<T>.class
到底是做什么的?
如果您查看它的构造函数,您会发现它就像一个类型信息的容器。通过执行 new ParameterizedTypeReference<List<Foo.class>> {};
,您在传入类型时实例化了一个匿名的 class。然后在构造函数中,它从传递的类型中提取类型信息并将其存储在内部。然后稍后我们可以做 getType()
来获取类型信息,这样我们就可以在运行时做一个类型安全的 "casting"。
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>"
此模式称为 "Super type tokens",您可以在此处阅读更多相关信息 Neal Gafter's blog - Super Type Tokens
我正在尝试使用 Spring RestTemplate 获取对象列表。我很困惑为什么选择 ParameterizedTypeReference 方法来使用 restTemplate 而不是仅使用 Object[].class?
来获取对象列表我检查了多个建议使用 ParameterizedTypeReference 的答案。但为什么我不能只使用 Object[].class?我有什么限制?
我已经检查了这个 link (
参数化类型引用方式:
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));
答案很简单,在运行时保留类型信息。
列表可以充当数组,但数组不能充当列表。为什么你正在做的事情是有效的,因为你正在将一个数组转换为一个列表,并且如上所述,一个列表可以充当一个数组,所以你这次是安全的。
但总的来说,铸造是一种不好的做法。
当你投射一些东西时,你是在冒险,你基本上是在强迫编译器"trust you"做你正在做的事情。因此,不是编译器告诉你什么是对的或错的,而是你告诉编译器什么是对的和错的,这是一种风险,破坏东西的风险。很难,因为 如果你在运行时出错,我们可能会崩溃。难以控制。
有很多程序员有很多意见,但只有一个编译器,一个意见,我们应该相信它。
回到问题,ParameterizedTypeReference<T>.class
到底是做什么的?
如果您查看它的构造函数,您会发现它就像一个类型信息的容器。通过执行 new ParameterizedTypeReference<List<Foo.class>> {};
,您在传入类型时实例化了一个匿名的 class。然后在构造函数中,它从传递的类型中提取类型信息并将其存储在内部。然后稍后我们可以做 getType()
来获取类型信息,这样我们就可以在运行时做一个类型安全的 "casting"。
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>"
此模式称为 "Super type tokens",您可以在此处阅读更多相关信息 Neal Gafter's blog - Super Type Tokens