所有,我可能对Java中的泛型有一个基本的误解,
为什么我们不能编写一个 Java 泛型子类来继承它的父泛型类?
定义如下:
public class JsonResponse<T> implements Response {
}
但是我定义了一个另一个子类来继承它:
public class MeetingClientResponse<T> extends JsonResponse<T> {
}
我将另一个调用类定义为:
public interface HttpExecutor<T extends Response> {
}
IMPL IT类是:
public class DefaultHttpExecutor<T extends Response> implements HttpExecutor<T> {
public DefaultHttpExecutor(ResponseHandler<T> responseHandler) {
this.responseHandler = responseHandler;
}
}
public class JsonResponseHandler<T> implements ResponseHandler<JsonResponse<T>> {
}
public class ScheduleMeetingResponseHandler extends
JsonResponseHandler<ScheduleMeetingResponseVO> {
}
handler = ScheduleMeetingResponseHandler.newIntance()
当我这样使用时,它没有编译错误:
HttpExecutor<JsonResponse<ScheduleMeetingResponseVO>> httpExecutor =
new DefaultHttpExecutor
<JsonResponse<ScheduleMeetingResponseVO>>(handler);
但是当我这样使用时,它会在 Eclipse 中编译错误:
HttpExecutor<MeetingClientResponse<ScheduleMeetingResponseVO>> httpExecutor =
new DefaultHttpExecutor
<MeetingClientResponse<ScheduleMeetingResponseVO>>(handler);
Eclipse 提示错误为:构造函数 DefaultHttpExecutor 未定义
将DefaultHttpExecutor
构造函数声明为
public DefaultHttpExecutor(ResponseHandler<? super T> responseHandler)
这是因为您正在尝试为MeetingClientResponse
创建一个DefaultHttpExecutor
,但是您正在向其传递一个用于JsonResponse
的处理程序。
通过该声明,您声明执行器将能够使用特定于MeetingClientResponse
的处理程序,或者可以使用特定类型的超类型满足的更通用处理程序。
参见 什么是PECS(生产者扩展消费者超级)?
DefaultHttpExecutor<T>
构造函数需要一个ResponseHandler<T>
参数。更准确地说,它期望一个声明为ResponseHandler<T>
的参数。因此,您需要将处理程序声明为ResponseHandler<MeetingClientResponse<ScheduleMeetingResponseVO>>
(或子类型):
ResponseHandler<MeetingClientResponse<ScheduleMeetingResponseVO>> handler;
我强调声明这个词,因为声明才是最重要的。如果您的处理程序被声明为 ResponseHandler<JsonResponse<ScheduleMeetingResponseVO>>
,则即使您的处理程序实际上是ResponseHandler<MeetingClientResponse<ScheduleMeetingResponseVO>>
,您也会收到编译错误。