为啥 Java Generic 不能设计为继承到父 Generic 类?
Posted
技术标签:
【中文标题】为啥 Java Generic 不能设计为继承到父 Generic 类?【英文标题】:Why Java Generic can't design to inherit to a parent Generic class?为什么 Java Generic 不能设计为继承到父 Generic 类? 【发布时间】:2013-10-21 22:15:01 【问题描述】:各位,我可能对 Java 中的 Generic 有一个基本的误解,
为什么我们不能写一个 Java Generic 子类来继承它的父 Generic 类?
定义如:
public class JsonResponse<T> implements Response
但我定义了另一个子类来继承它:
public class MeetingClientResponse<T> extends JsonResponse<T>
我将另一个调用者类定义为:
public interface HttpExecutor<T extends Response>
实现它的类是:
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 未定义
【问题讨论】:
这两个声明都可以在 Eclipse 上正常编译。 你得到什么错误信息? 你能指定你在 Eclipse 中遇到的错误吗? 构造函数 DefaultHttpExecutor 未定义 @JerryCai 如果只显示,应该为他们两个显示该错误。你的handler
是如何声明的?
【参考方案1】:
将DefaultHttpExecutor
构造函数声明为
public DefaultHttpExecutor(ResponseHandler<? super T> responseHandler)
这是因为您尝试为MeetingClientResponse
创建一个DefaultHttpExecutor
,但您传递给它的是一个用于JsonResponse
的处理程序。
通过该声明,您声明执行程序将能够使用特定于 MeetingClientResponse
的处理程序,或者可以满足特定类型的超类型的更多通用处理程序。
另见What is PECS (Producer Extends Consumer Super)?
【讨论】:
【参考方案2】:DefaultHttpExecutor<T>
构造函数需要一个 ResponseHandler<T>
参数。更准确地说,它期望参数声明为ResponseHandler<T>
。因此,您需要将处理程序声明为ResponseHandler<MeetingClientResponse<ScheduleMeetingResponseVO>>
(或子类型):
ResponseHandler<MeetingClientResponse<ScheduleMeetingResponseVO>> handler;
我强调了声明这个词,因为声明才是最重要的。如果你的处理程序被声明为ResponseHandler<JsonResponse<ScheduleMeetingResponseVO>>
,你会得到一个编译错误,即使你的处理程序实际上是一个ResponseHandler<MeetingClientResponse<ScheduleMeetingResponseVO>>
。
【讨论】:
以上是关于为啥 Java Generic 不能设计为继承到父 Generic 类?的主要内容,如果未能解决你的问题,请参考以下文章