Java 7 泛型:如何访问泛型类型的方法?
Java 7 Generic: How to access method of generic type?
我正在开发一个使用 Java 7 的遗留应用程序。我有一个通用请求 class(注释来自 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);
}
这里是这个接口的实现者class:
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 class 中,没有 getter 可用于通用类型 studentRequestContext 对象。我错过了什么?
只是为了让你明白
<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
的确切语法。
public <StudentRequestContext> Response getResponse(...
表示您将 StudentRequestContext
声明为 类型变量 ,此方法对其具有通用性。它与上面名为 StudentRequestContext
的 class 完全无关。当您在方法内部使用类型 StudentRequestContext
时,它指的是为此方法声明的类型变量,而不是 class.
中的类型
为避免混淆,您可以将类型变量重命名为,比方说,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);
意味着实现方法必须接受 任何 类型参数的 Request
类型的参数(您可以等效地将签名写为 Response getResponse(Request<?> request);
).
你可能想要的是使接口通用,并让它的 getResponse
方法接受一个特定类型参数的 Request
类型的参数,该类型参数与类型参数相同ResponseGenerator
本身:
public interface ResponseGenerator<T> {
Response getResponse(Request<T> request);
}
然后你的 StudentResponseGenerator
class 可以使用特定类型作为类型参数来实现该接口:
public class StudentResponseGenerator implements ResponseGenerator<StudentRequestContext> {
@Override
public Response getResponse(Request<StudentRequestContext> studentRequest) {
// ...
}
}
我正在开发一个使用 Java 7 的遗留应用程序。我有一个通用请求 class(注释来自 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);
}
这里是这个接口的实现者class:
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 class 中,没有 getter 可用于通用类型 studentRequestContext 对象。我错过了什么?
只是为了让你明白
<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
的确切语法。
public <StudentRequestContext> Response getResponse(...
表示您将 StudentRequestContext
声明为 类型变量 ,此方法对其具有通用性。它与上面名为 StudentRequestContext
的 class 完全无关。当您在方法内部使用类型 StudentRequestContext
时,它指的是为此方法声明的类型变量,而不是 class.
为避免混淆,您可以将类型变量重命名为,比方说,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);
意味着实现方法必须接受 任何 类型参数的 Request
类型的参数(您可以等效地将签名写为 Response getResponse(Request<?> request);
).
你可能想要的是使接口通用,并让它的 getResponse
方法接受一个特定类型参数的 Request
类型的参数,该类型参数与类型参数相同ResponseGenerator
本身:
public interface ResponseGenerator<T> {
Response getResponse(Request<T> request);
}
然后你的 StudentResponseGenerator
class 可以使用特定类型作为类型参数来实现该接口:
public class StudentResponseGenerator implements ResponseGenerator<StudentRequestContext> {
@Override
public Response getResponse(Request<StudentRequestContext> studentRequest) {
// ...
}
}