如何使用泛型进行类型安全? [英] How to make type safety with generics?

查看:155
本文介绍了如何使用泛型进行类型安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有班级

 公共类ReportItem< ReportType扩展报表> {} 

和类

  public abstract class Report实现了Iterable< ReportItem> {

private List< ReportItem<扩展报告> > itemList中;

public void add(ReportItem< ;? extends Report> item){
itemList.add(item);
}

//一些其他人员

}

公共类ConcreteReport扩展报告{
//某些人员

事情是方法 add(ReportItem< ;? extends Report>)是不安全的,因为我可以提供的项目不与当前报告绑定,但与另一个绑定,编译器不会发生抱怨。



是否有可能以类型安全的方式编写方法 add ,也就是说我们可以只传递 ReportItem< ; T> 其中T是当前报告的类型。

  public abstract class Report< T extends Report< T>>实现Iterable< ReportItem< T>> {

private List< ReportItem< T>> itemList中;

public void add(ReportItem< T> item){
itemList.add(item);
}

//一些其他的东西

}

公共类ConcreteReport extends Report< ConcreteReport> {
//某些东西
}

它的工作方式是:




  • 您想要将 ReportItem< T> c $ c> Report

  • 您需要确保 ReportItem< T> 所有列表全部属于相同类型的报表



为了绑定<$ code> ReportItem< T> 的参数添加到 Report ,您需要参数化 Report 本身:

  public abstract class Report< ; T>实现了Iterable< ReportItem< T>> 

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

  public abstract class Report< T extends Report>实现了Iterable< ReportItem< T>> 

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

  public abstract class Report< T extends Report< T>>实现了Iterable< ReportItem< T>> 

通过这种方式,您可以参数化 List< ReportItem< T>> / code>以及您扩展的具体类型:

  public class ConcreteReport extends Report< ConcreteReport> {b $ b  

这样,列表将会是

  public List< ReportItem< ConcreteReport>> ITEMLIST; 

这就是你想要的。



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


I have the class

public class ReportItem<ReportType extends Report>{ }

and the 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
}

The thing is the method add(ReportItem<? extends Report>) is unsafe in the way I could provide items aren't tied with the current report, but tied with some another and the compiler won't complain.

Is it possible to write the method add in a type-safe way, i.e. we could pass as an argument only that ReportItem<T> where T is the type of a current report.

解决方案

I think you are looking for the following.

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
}

The way it works is that:

  • You want to parametrize ReportItem<T> with something that extends from Report
  • You want to make sure that the list of ReportItem<T> all belong to the same type of Report

In order to bind the T parameter of ReportItem<T> to something that extends from Report, you need to parametrize the Report itself:

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

you add the bind that it needs to extend from Report

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

But you are specifying the bound for the raw type of report, which doesn't work, so you need to provide Report with the type parameter that the report receives, which is T.

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

This way you can parametrize the List<ReportItem<T>> with the concrete type that you extend with:

public class ConcreteReport extends Report<ConcreteReport> { 

This way the list will be

public List<ReportItem<ConcreteReport>> itemlist;

Which is what you wanted.

And it works! :) I just hope my explanation of it makes sense.

这篇关于如何使用泛型进行类型安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆