我正在使用Java 7的旧版应用程序上工作。我有一个通用的Request类(注释来自lombok):
@AllArgsConstructor
@Getter
public class Request<T> {
int Id;
T requestContext;
}
这是requestContext类型之一:
@AllArgsConstructor
@Getter
public class StudentRequestContext {
int ID;
String name;
}
我有一个ResponseGenerator接口:
public interface ResponseGenerator {
<T> Response getResponse(Request<T> request);
}
这是此接口的实现程序类:
public class StudentResponseGenerator implements ResponseGenerator {
@Override
public <StudentRequestContext> Response getResponse(
Request<StudentRequestContext> studentRequest) {
StudentRequestContext studentRequestContext =
(StudentRequestContext) studentRequest.getRequestContext();
studentRequestContext.get //NO getName METHOD IS AVAILABLE
}
}
如上面的代码注释所示,在StudentResponseGenerator类中的通用类型StudentRequestContext对象没有可用的吸气剂。我想念什么?
答案 0 :(得分:1)
public <StudentRequestContext> Response getResponse(...
表示您将StudentRequestContext
声明为该方法通用的类型变量。它与上面名为StudentRequestContext
的类完全无关。当您在方法内部使用类型StudentRequestContext
时,它引用的是为此方法声明的类型变量,而不是类中的类型。
为避免混淆,您可以将类型变量重命名为U
,它与上面的内容完全等效:
public <U> Response getResponse(
Request<U> studentRequest) {
U studentRequestContext =
(U) studentRequest.getRequestContext();
studentRequestContext.get //NO getName METHOD IS AVAILABLE
}
看看是什么问题?变量studentRequestContext
的类型为U
(无边界的类型变量),没有名为getName
的方法。
签名<T> Response getResponse(Request<T> request);
所表示的含义与您可能想要的有所不同。签名<T> Response getResponse(Request<T> request);
表示实现方法必须接受 any 类型参数的Request
类型的参数(您可以等效地将签名写为Response getResponse(Request<?> request);
)。 / p>
您可能想要使接口通用,并使它的getResponse
方法接受特定类型参数的Request
类型的参数,该参数与{的类型参数相同{1}}本身:
ResponseGenerator
然后您的public interface ResponseGenerator<T> {
Response getResponse(Request<T> request);
}
类可以使用特定类型作为类型参数来实现该接口:
StudentResponseGenerator
答案 1 :(得分:0)
只是为了让您了解
<T> Response getResponse(Request<T> request)
^ ^
| actual return type of the method
type used with the 'request' parameter, needed to type bind args which are generic
因此实现应类似于
public class StudentResponseGenerator implements ResponseGenerator {
@Override
public Response getResponse(
Request<StudentRequestContext> studentRequest) { // this is where the T is inferred
StudentRequestContext studentRequestContext =
(StudentRequestContext) studentRequest.getRequestContext();
return Response.entity(studentRequestContext.getName()).build();
}
}
注意 :我尚未编译当前构建Response
的确切语法。