I was looking at a relatively simple block of code that hit the database and returned the results as a LinkedList. It seemed obvious that the SQL should be injected but then it occurred to me that the LinkedList was an unnecessary dependency too.
The simplified version is as follows:
public List<String> getStrings() {
//Hard coded reference to LinkedList
List<String> tmp = new LinkedList<String>();
tmp.add("foo");
return tmp;
}
I tried to rewrite it to let me specify the List implementation at runtime.
Calling getStrings(Class< List > listType) with getStrings(LinkedList.class) gives an error about the method not being applicable. The following works ok:
public List getStrings(Class<? extends List> listType) throws InstantiationException, IllegalAccessException {
List tmp = listType.newInstance();
tmp.add("foo");
return tmp;
}
public void caller() throws InstantiationException, IllegalAccessException {
List stringList = getStrings(LinkedList.class);
}
However all the references to List and tmp complain about type safety because it really should be List< String >.
Adding the generic works ok at getStrings():
public List<String> getStrings(Class<? extends List<String>> listType) throws InstantiationException, IllegalAccessException {
List<String> tmp = listType.newInstance();
tmp.add("foo");
return tmp;
}
but the updated call doesn't compile at all:
getStrings(LinkedList<String>.class);
The following works, but gives me an unchecked cast warning:
getStrings((Class<? extends List<String>>) LinkedList.class);
Is there a Right Way(tm) to do this?
As you've discovered, runtime reflection doesn't mix well with compile-time generics. If you're using Java 8, I would suggest a much cleaner and safer approach:
public List<String> getStrings(Supplier<List<String>> listSupplier) {
List<String> tmp = listSupplier.get();
tmp.add("foo");
return tmp;
}
public void caller() {
List<String> stringList = getStrings(LinkedList::new);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.