2015-06-03 31 views
4

我有类如何使用泛型进行类型安全?

public class ReportItem<ReportType extends Report>{ } 

和类

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是当前报表的类型。

回答

4

我认为你正在寻找以下。

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与报告接收的类型参数,即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; 

这是你想要的。

它的工作原理! :)我只希望我的解释是有道理的。

+2

ReportType是类型参数 – user3663882

+0

好吧,现在检查。我认为这应该是你想要的。 – EpicPandaForce

+1

Wokrs现在完美。但是报告<报告>看起来有点复杂。你不能给一点解释吗? – user3663882