2016-05-02 34 views
0

我有一個名爲ReportWriter,這寫報告的OutputStream,其中包含reportRow列表報告類的界面,也是一個抽象類:的Java interferface與通用類及其實施

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. 

我不明白在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. 

我怎樣才能解決這個問題?謝謝

+0

這裏的根本問題是你混合了參數化類型和原始類型。您應該閱讀[什麼是原始類型,爲什麼我們不應該使用它?](http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we -用它) –

回答

6

你需要指定你使用泛型類型實現接口:

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

(注意ReportWriter<T>

3

我還沒有測試,但可能是因爲您在繼承時使用了原始類型。嘗試以下代碼塊:

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

請注意ReportWriter上額外的<T>

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類型的變量(顯然)。