关于java:如何使用泛型使类型安全?

How to make type safety with generics?

我上课了

1
public class ReportItem<ReportType extends Report>{ }

和班级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)不安全,因为我可以提供与当前报表无关的项,但与其他项绑定,编译器不会抱怨。

是否可以以类型安全的方式编写方法add,即我们只能将其中t是当前报表类型的ReportItem作为参数传递。


我想你在找以下的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
}

其工作方式是:

  • 你想用从Report延伸出来的东西来参数化ReportItem
  • 您要确保EDOCX1[0]的列表都属于同一类型的EDOCX1[1]

为了将ReportItemT参数绑定到从Report扩展的对象上,需要对Report本身进行参数化:

1
public abstract class Report<T> implements Iterable<ReportItem<T>>

添加它需要从报表扩展的绑定

1
public abstract class Report<T extends Report> implements Iterable<ReportItem<T>>

但是您指定的是原始报表类型的界限,这不起作用,因此需要向Report提供报表接收的类型参数,即T

1
public abstract class Report<T extends Report<T>> implements Iterable<ReportItem<T>>

通过这种方式,您可以使用扩展的具体类型对List>进行参数化:

1
public class ConcreteReport extends Report<ConcreteReport> {

这样列表就会

1
public List<ReportItem<ConcreteReport>> itemlist;

这就是你想要的。

它工作!我只是希望我对它的解释是有意义的。