Reputation: 31020
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?
Upvotes: 2
Views: 74
Reputation: 95528
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:
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. It appears that read
always returns 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. 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. 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
}
}
Upvotes: 1
Reputation: 20618
A DataReader
operates on some unknown type of data items. 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. As far as I can see you want it to operate on a List<String>
- representing a CSV row, I think.
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 { ... }
}
Upvotes: 1
Reputation: 24630
To override a method the signatures must be match.
public class CSVReader<E extends List> extends DataReader<E>
Upvotes: 1
Reputation: 1273
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;
}
Upvotes: 0