【问题标题】:How to make type safety with generics?如何使用泛型实现类型安全?
【发布时间】:2015-06-03 10:00:48
【问题描述】:

我有课

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&lt;? extends Report&gt;) 方法不安全,因为我可以提供的项目与当前报告无关,但与其他报告相关,编译器不会抱怨。

是否可以以类型安全的方式编写方法 add,即我们可以仅将 ReportItem&lt;T&gt; 作为参数传递,其中 T 是当前报告的类型。

【问题讨论】:

    标签: java generics


    【解决方案1】:

    我认为您正在寻找以下内容。

    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&lt;T&gt; 进行参数化
    • 您要确保ReportItem&lt;T&gt; 的列表都属于Report 的同一类型

    为了将ReportItem&lt;T&gt; 的T 参数绑定到从Report 扩展的东西,您需要参数化Report 本身:

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

    您添加它需要从 Report 扩展的绑定

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

    但是你为报告的原始类型指定了界限,这不起作用,所以你需要提供Report报告接收的类型参数,即@987654333 @。

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

    这样您可以使用您扩展的具体类型参数化List&lt;ReportItem&lt;T&gt;&gt;:

    public class ConcreteReport extends Report<ConcreteReport> { 
    

    这样列表将是

    public List<ReportItem<ConcreteReport>> itemlist;
    

    这是你想要的。

    而且它有效! :) 我只是希望我的解释是有道理的。

    【讨论】:

    • ReportType 是一个类型参数
    • 好的,现在检查。我想这应该是你想要的。
    • 现在工作完美。但是声明Report&lt;T extends Report&lt;T&gt;&gt; 看起来有点复杂。不能稍微解释一下吗?
    • 塔恩克的解释。明白了。
    • @EpicPandaForce:哦,我忘了,当你有两种类型时需要它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多