您好我试图将通用方法实现为控制器基本方法,但是我无法理解的问题发生在泛型方法签名上。
<T> ResponseEntity<T> makeApiCall(String path, HttpMethod httpMethod, T body, boolean isAdmin){
String sender = isAdmin ? adminHash : userHash;
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", sender);
headers.add("Content-Type", "application/json");
HttpEntity<T> entity = new HttpEntity<>(body,headers);
ResponseEntity<T> responseEntity = restTemplate.exchange(path, HttpMethod.POST, entity, body.getClass());
return responseEntity;
}
我目前的编译错误如下:
Incompatible equality constraint: T and capture of ? extends Object
答案 0 :(得分:4)
您没有准确说出问题发生的位置,但我认为这会在restTemplate.exchange(
调用中发生,因为将body.getClass()
作为参数传递。这是因为body.getClass()
的返回类型为Class<? extends Object>
,as in the Javadoc:
实际结果类型为
Class<? extends |X|>
,其中|X|
是删除调用getClass
的表达式的静态类型
问题在于,您无法保证body
具体为T
- 它可能是T
的子类。因此,body.getClass()
的结果可能不是Class<T>
。
如果您想要是类型安全的,则需要将其作为附加参数传递给方法。
<T> ResponseEntity<T> makeApiCall(
String path, HttpMethod httpMethod, T body, Class<T> bodyClass,
boolean isAdmin){
// ...
ResponseEntity<T> responseEntity =
restTemplate.exchange(
path, HttpMethod.POST, entity, bodyClass);
// ...
}
请注意,获取Class<T>
的唯一方法是使用类文字,例如如果String.class
为T
,则为String
。这排除了使用通用的体型,因为没有通用的类文字。
答案 1 :(得分:2)
您需要cast body.getClass()
到Class<T>
@SuppressWarnings("unchecked")
<T> ResponseEntity<T> makeApiCall(String path, HttpMethod httpMethod, T body, boolean isAdmin){
String sender = isAdmin ? adminHash : userHash;
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", sender);
headers.add("Content-Type", "application/json");
HttpEntity<T> entity = new HttpEntity<>(body,headers);
ResponseEntity<T> responseEntity = restTemplate.exchange(path, HttpMethod.POST, entity, (Class<T>) body.getClass());
return responseEntity;
}
要使其类型安全,您需要明确地将类对象作为参数传递:
<T> ResponseEntity<T> makeApiCall(String path, HttpMethod httpMethod, T body, Class<T> clazz, boolean isAdmin){
String sender = isAdmin ? adminHash : userHash;
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", sender);
headers.add("Content-Type", "application/json");
HttpEntity<T> entity = new HttpEntity<>(body,headers);
ResponseEntity<T> responseEntity = restTemplate.exchange(path, HttpMethod.POST, entity, clazz);
return responseEntity;
}