[英]inherited methods in java generics
I'm not sure how generics works when overwriting a method in the child class. 我不确定在子类中重写方法时泛型如何工作。
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
}
}
error 错误
Type mismatch: cannot convert from List<String> to E CSVReader.java
How do I fix this? 我该如何解决?
In general, when extending a genericized class, need to specify the generic type in your extended class' signature as well: 通常,在扩展通用类时,还需要在扩展类的签名中指定通用类型:
public class CSVReader<T> extends DataReader<T> {
...
@Override
public T readNext() throws IOException {
...
}
}
In your case, where you want a List
, you can get more specific and do this: 在您的情况下,如果您需要一个
List
,则可以更具体地执行以下操作:
public class CSVReader<T extends List<E>> extends DataReader<T> {
...
@Override
public List<E> readNext() throws IOException {
...
}
}
I took a look at ICsvListReader
and the class is not genericized, which will make your implementation of readNext()
somewhat problematic. 我看了一下
ICsvListReader
,但该类没有被泛化,这会使readNext()
有些问题。 It appears that read
always returns List<String>
. 似乎
read
总是返回List<String>
。 So if someone instantiates an instance of CSVReader
that is CSVReader<List<Integer>>
then you're in trouble (heap pollution) because readNext
is returning List<String>
, and then you'll end up with a ClassCastException
when you try to access elements of the list. 因此,如果有人实例化了
CSVReader<List<Integer>>
的CSVReader
实例,则您会遇到麻烦(堆污染),因为readNext
返回List<String>
,而当您尝试执行以下操作时,您将最终遇到ClassCastException
访问列表的元素。 The compiler may warn you (I think Java 7 does) but the code will actually compile because generic types are lost at runtime due to type erasure. 编译器可能会警告您(我想Java 7会警告您),但是代码实际上会编译,因为泛型由于类型擦除而在运行时丢失。 Hence in this case I think it's better to be really explicit and do this instead:
因此,在这种情况下,我认为最好是显式地执行此操作:
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
}
}
要覆盖方法,签名必须匹配。
public class CSVReader<E extends List> extends DataReader<E>
A DataReader
operates on some unknown type of data items. DataReader
对某些未知类型的数据项进行操作。 This is the reason why it is declared as a generic class: 这就是为什么将其声明为泛型类的原因:
public abstract class DataReader<T> { ... }
Your CSVReader
sub class already knows the concrete type of data items it operates with. 您的
CSVReader
子类已经知道其处理的数据项的具体类型 。 As far as I can see you want it to operate on a List<String>
- representing a CSV row, I think. 据我所知,您希望它对
List<String>
进行操作-代表CSV行。
With that in mind, you simply must declare your class a bit more concrete: 考虑到这一点,您只需要声明您的类更加具体:
public class CSVReader extends DataReader<List<String>> {
@Override
public List<String> readNext() throws IOException { ... }
}
You say you return a generic type in the function definition but return a list in the function itself. 您说您在函数定义中返回通用类型,但在函数本身中返回列表。 Fix it like this:
像这样修复它:
public <E> List<E> readNext() {
java.util.List<E> line= reader.read();
return line;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.