繁体   English   中英

Java与通用类的接口及其实现

[英]Java interferface with Generic class and its implementation

我有一个名为ReportWriter的接口,该接口将报告写入OutputStream,Report类包含reportRow的列表,它也是一个抽象类:

public interface ReportWriter<T extends ReportRow> {
    OutputStream writeReport(Report<T> report) throws ReportWriterException;
}

public abstract class Report<T extends ReportRow> {
   private List<T> rows = Lists.newArrayList();
   ...
}

public abstract class ReportRow {...}

现在我有了实现ReportWriter的CsvWriter,

public class CsvWriter<T extends ReportRow> implements ReportWriter {
        @Override
        public ByteArrayOutputStream writeReport(Report report) throws ReportWriterException {
        ...
         for (T row : report.getRows()) {  <-- incompatible type
               ..write here..
         }
}

在上面的代码中,它抱怨类型不兼容:

require Object found T. 

我在Report类中不了解,我已指定T为ReportRow的子类,为什么会收到此投诉?

然后,我尝试如下更新CsvWriter的writeReport:

public class CsvWriter<T extends ReportRow> implements ReportWriter {
   @Override
   public ByteArrayOutputStream writeReport(Report<T> report) throws ReportWriterException {  <--- complain here
...
}

现在它抱怨:

writeReport(Report<T> report) clashes with writeReport(Report report); both methods have same erasure.

我怎样才能解决这个问题? 谢谢

您需要使用通用类型指定要实现的接口:

public class CsvWriter<T extends ReportRow> implements ReportWriter<T> {

(请注意ReportWriter<T>

我尚未对此进行测试,但是可能是因为您在继承时使用了原始类型。 尝试第二个代码块:

public class CsvWriter<T extends ReportRow> implements ReportWriter<T> {...

请注意ReportWriter上额外的<T>

让我们来谈谈这个片段:

public class CsvWriter<T extends ReportRow> implements ReportWriter {
    @Override
    public ByteArrayOutputStream writeReport(Report report) throws ReportWriterException {
        ...
        for (T row : report.getRows()) {  <-- incompatible type
        ..write here..
    }
}

如果没有泛型类型参数, ReportWriter扩展的ReportWriter<ReportRow>成为ReportWriter<ReportRow> 这意味着report.getRows()将返回List<ReportRow>

但是您正在尝试将其元素赋给类型T的变量。 T extends ReportRow 因此T可能是ReportRow的子类。

如果是这样,则您正在执行隐式向下转换,因此编译器将引发错误。


通过扩展ReportWriter<T>getReport()现在将返回List<T> ,并且可以安全地将元素分配给类型T变量(显然)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM