【开源中国 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"));
你的dist集合显然只能存储Exception和其子类,并不能包括Throwable;
另外,由于Exception是Throwable的子类,所以下面这句并不会报错
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时不会出错。