Simply put: You can't do that.
You can only instantiate an Object reflectively if you have the .class
object for it, or an instance of the class you can retrieve it from. However, if you change your method signature as follows:
public static <T extends List<String>> void parse(String[] args, List<String> params, Map<String, T> options, Set<String> flags, Set<String> flagSet, Class<T> klass) throws InstantiationException, IllegalAccessException
Then when you call it add MyStringList.class
(or whatever the map value type is), you can change your constructor line to:
options.put(p, klass.newInstance());
And your code should work as expected.
Edit:
I get this => Test.java:19: illegal start of expression
Pinput.parse(args, params, options, flags, flagSet,
ArrayList<String>.class);
ArrayList<String>
does not extend List<String>
, ArrayList<T>
extends List<T>
and String
extends Object
which means it's valid as T
. This would only work with a class declared as:
class MyStringList extends List<String>
Generics are not really appropriate for what you are trying to do, really you should just use this as your signature:
public static void parse(String[] args, List<String> params, Map<String, List<String>> options, Set<String> flags, Set<String> flagSet)
And manually instantiate the list as an ArrayList
:
options.put(arg, new ArrayList<String>());
As List
is only an interface, the compiler knows that you will provide some implementation of that interface, and then only allow you access to the List
methods.