在覆盖子类中的方法时,我不确定泛型是如何工作的。
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
我该如何解决这个问题?
答案 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;
}