Java干扰与Generic类及其实现

时间:2016-05-02 16:32:13

标签: java generics interface

我有一个名为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 {...}

现在我有CsvWriter实现ReportWriter,

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. 

我不会&#39;在报告类中明白我已经指定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.

我该如何解决这个问题?感谢

3 个答案:

答案 0 :(得分:6)

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

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

(请注意ReportWriter<T>

答案 1 :(得分:3)

我还没有对此进行测试,但可能是因为你在继承时使用了原始类型。试试这个第二个代码块:

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

请注意ReportWriter上的额外<T>

答案 2 :(得分:0)

我们来谈谈这个片段:

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>。这意味着report.getRows()将返回List<ReportRow>

但是你试图将它的元素分配给T类型的变量。这是T extends ReportRow。因此T可能是ReportRow的子类。

如果是,则表示您正在执行隐式向下转换,因此编译器会抛出错误。

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