我有课
public class ReportItem<ReportType extends Report>{ }
和 class
public abstract class Report implements Iterable<ReportItem>{
private List<ReportItem<? extends Report> > itemList;
public void add(ReportItem<? extends Report> item){
itemList.add(item);
}
//Some other staff
}
public class ConcreteReport extends Report{
//Some staff
}
事情是,
add(ReportItem<? extends Report>)
方法不安全,因为我可以提供的项目与当前报告无关,但与其他报告相关,编译器不会抱怨。是否可以以类型安全的方式编写方法
add
,即我们可以仅将ReportItem<T>
作为参数传递,其中T是当前报表的类型。 最佳答案
我认为您正在寻找以下内容。
public abstract class Report<T extends Report<T>> implements Iterable<ReportItem<T>>{
private List<ReportItem<T>> itemList;
public void add(ReportItem<T> item){
itemList.add(item);
}
//Some other stuff
}
public class ConcreteReport extends Report<ConcreteReport> {
//Some stuff
}
它的工作方式是:
ReportItem<T>
扩展到Report
进行参数化ReportItem<T>
列表都属于同一类型的Report
为了将
T
的ReportItem<T>
参数绑定到Report
扩展的内容,您需要参数化Report
本身:public abstract class Report<T> implements Iterable<ReportItem<T>>
您添加需要从报表扩展的绑定
public abstract class Report<T extends Report> implements Iterable<ReportItem<T>>
但是,您要为报告的原始类型指定界限,该界限不起作用,因此您需要为
Report
提供报告接收的type参数,即T
。public abstract class Report<T extends Report<T>> implements Iterable<ReportItem<T>>
这样,您可以使用扩展的具体类型来参数化
List<ReportItem<T>>
:public class ConcreteReport extends Report<ConcreteReport> {
这样列表将
public List<ReportItem<ConcreteReport>> itemlist;
这就是你想要的。
而且有效! :)我只是希望我的解释有意义。