为什么Java Generic无法设计继承到父Generic类?

时间:2013-10-14 10:57:18

标签: java generics inheritance

所有,我可能对Java中的Generic有一个基本的误解,

为什么我们不能编写Java Generic子类来继承其父Generic类?

定义如:

public class JsonResponse<T> implements Response {
}

但我定义了另一个继承它的子类:

public class MeetingClientResponse<T> extends JsonResponse<T> {
}

我将另一个调用者类定义为:

public interface HttpExecutor<T extends Response> {
}

impl it class is:

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 tip错误为:构造函数DefaultHttpExecutor未定义

2 个答案:

答案 0 :(得分:1)

将您的DefaultHttpExecutor构造函数声明为

public DefaultHttpExecutor(ResponseHandler<? super T> responseHandler)

这是因为您尝试为DefaultHttpExecutor创建MeetingClientResponse,但是您正在向它传递一个用于JsonResponse的处理程序。

使用该声明,您声明执行程序将能够使用特定于MeetingClientResponse的处理程序,或更多通用处理程序,这些处理程序可以满足特定类型的超类型。

另见What is PECS (Producer Extends Consumer Super)?

答案 1 :(得分:0)

DefaultHttpExecutor<T>构造函数需要ResponseHandler<T>参数。更准确地说,它期望参数声明ResponseHandler<T>。因此,您需要将声明处理程序作为ResponseHandler<MeetingClientResponse<ScheduleMeetingResponseVO>>(或子类型):

ResponseHandler<MeetingClientResponse<ScheduleMeetingResponseVO>> handler;

我强调了声明这个词,因为声明才是最重要的。如果您的处理程序被声明为ResponseHandler<JsonResponse<ScheduleMeetingResponseVO>>,则会出现编译错误,即使您的处理程序实际上是ResponseHandler<MeetingClientResponse<ScheduleMeetingResponseVO>>