Reputation: 3171
I have a SimpleMapper
which has a constructor taking ResultSet
as param:
public abstract class SimpleMapper{
public SimpleMapper() {}
public SimpleMapper(ResultSet rs) {}
}
...and I have several subclass from SimpleMapper
.
Now I want to write a generic method, converting ResultSet
to List<T>
where T
is subclass of SimpleMapper
.
Here is the code:
public static <T extends SimpleMapper> List<T> resultSetToList(ResultSet rs, Class<? extends SimpleMapper> clazz) throws SQLException {
List<T> list = new ArrayList<>();
while (rs.next()) {
list.add(clazz.getConstructor(new Class[]{ResultSet.class}).newInstance(rs));
}
return list;
}
The compiler is giving this error:
The method add(T) in the type List<T> is not applicable for the arguments (capture#2-of ? extends SimpleMapper)
What am I doing wrong here? I've specified T
to be subclass of SimlpeMapper
.
Upvotes: 1
Views: 94
Reputation: 271040
Rather than taking a Class<? extends SimpleMapper>
, you should take a Class<T>
. This makes sure that the class' constructor produces the same type as the type of list that you are returning:
public static <T extends SimpleMapper> List<T> resultSetToList(ResultSet rs, Class<T> clazz)
throws SQLException {
try {
List<T> list = new ArrayList<>();
while (rs.next()) {
list.add(clazz.getConstructor(ResultSet.class).newInstance(rs));
}
return list;
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
// handle the exception in some way...
// maybe rethrow a RuntimeException?
throw new RuntimeException("Exception occurred during reflection!", e);
}
}
Upvotes: 4