java 中超类型通配符问题。

小墨雨 发布于 2016/09/11 21:26
阅读 281
收藏 1

【开源中国 APP 全新上线】“动弹” 回归、集成大模型对话、畅读技术报告”

问题:将存储Exception的父类对象(Throwable)赋值给 dlist(里面定义存储的对象是Exception或者Exception子类), 那为什么不可以直接add Throable对象呢。为什么最后一行报编译错误,

ArrayList<Throwable> throwables = new ArrayList<Throwable>();
throwables.add(new Throwable("d"));
List<? super Exception> dlist = throwables;
dlist.add(new IOException("d")); 
//下面这行编译错误,为什么呢?
 //dlist.add(new Throwable("d"));


加载中
0
_
_Yud
因为你的dlist只允许放exception, throwables才能放Throwable
小墨雨
那为什么能dlist.add(new IOException("d"));
0
松梓
松梓
搞清楚继承关系:
Throwable是所有异常和错误的超类;

Exception是所有异常的超类;

你的dist集合显然只能存储Exception和其子类,并不能包括Throwable;

 //dlist.add(new Throwable("d"));所以这句报错

另外,由于Exception是Throwable的子类,所以下面这句并不会报错


0
大止刀口
大止刀口

java 的 通配 ? super和? extends实际上是对叫括号内要代表的类型的限定,用于类型推导

不能简单的认为把类型代入?后成立就可以,而是要类型推导符合才行。

Java泛型这样的设计就造成了需要具体场景下的类型分析推导才能分辨是否可行,这就很不直观

这里主要说下 返回类型和参数类型。

void method(? super C);//参数是C的超类,只要是C的子类传进来都能确认没问题。

void method(? extends C);//参数是C的子类,不能确定C的子类究竟是哪一个,传什么都不对。

? super C method();//返回值是C的超类,不能确定C的超类是具体哪一个,只能确定是Object。

? extends C method();//返回值是C的子类,至少可以确定类型是C及其父类。

你的问题属于第1种,传? super Exception的参数只能确保类型至少是Exception时不会出错。

小墨雨
解释得很清楚,thanks~
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部