java泛型中继承的方法

时间:2014-09-17 06:03:06

标签: java generics

在覆盖子类中的方法时,我不确定泛型是如何工作的。

import com.fasterxml.sort.DataReader;

public class CSVReader<E> extends DataReader<E>
{

    private final ICsvListReader reader; 

    public CSVReader(InputStream in) {
        reader = new CsvListReader(new InputStreamReader(in), CsvPreference.STANDARD_PREFERENCE);
    }

    @Override
    public E readNext() throws IOException {
        java.util.List<String> line=reader.read();
        return line;//compilation error
    }
}

错误

Type mismatch: cannot convert from List<String> to E CSVReader.java 

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:1)

通常,在扩展泛化类时,还需要在扩展类的签名中指定泛型类型:

public class CSVReader<T> extends DataReader<T> {

   ...
   @Override
   public T readNext() throws IOException {
       ... 
   }
}

在您的情况下,您需要List,您可以更具体地执行此操作:

public class CSVReader<T extends List<E>> extends DataReader<T> {
   ...
   @Override
   public List<E> readNext() throws IOException {
       ... 
   }
}

我查看了ICsvListReader并且该类不是通用化,这将使您readNext()的实现有些问题。似乎read始终返回List<String>。因此,如果某人实例化了CSVReader CSVReader<List<Integer>>的实例,那么您遇到了麻烦(堆污染),因为readNext正在返回List<String>,然后您最终会当您尝试访问列表的元素时,使用ClassCastException。编译器可能会警告你(我认为Java 7会这样),但代码实际上会编译,因为泛型类型在运行时由于类型擦除而丢失。因此,在这种情况下,我认为最好是真正明确,而是这样做:

public class CSVReader extends DataReader<List<String>> {

   private final ICsvListReader reader; 

   ...

   @Override
   public List<String> readNext() throws IOException {
      return reader.read(); //read already throws an IOException so you're good to go
   }
}

答案 1 :(得分:1)

要覆盖方法,签名必须匹配。

public class CSVReader<E extends List> extends DataReader<E>

答案 2 :(得分:1)

DataReader对某些未知类型的数据项进行操作。这就是它被声明为泛型类的原因:

public abstract class DataReader<T> { ... }

您的CSVReader子类已经知道它运行的数据项的具体类型。据我所知,你希望它在List<String>上运行 - 代表一个CSV行。我想。

考虑到这一点,你只需要宣传你的课程更具体:

public class CSVReader extends DataReader<List<String>> {
    @Override
    public List<String> readNext() throws IOException { ... }
}

答案 3 :(得分:0)

您说您在函数定义中返回泛型类型,但在函数本身中返回一个列表。修复如下:

public <E> List<E> readNext() {
    java.util.List<E> line= reader.read();
    return line;
}