我希望能够创建一个新的实例吗?参数化类型,但我找不到办法。
import java.util.List;
import java.util.Map;
import java.util.Set;
class Pinput {
public static void parse (String[] args, List<String> params, Map<String, ? extends List<String>> options, Set<String> flags, Set<String> flagSet){
String optionalParameterKey;
Boolean isOptionalParameter = false;
for(int n = 0; n < args.length; ++n){
String p = args[n];
if (p.charAt(0) == '-'){
isOptionalParameter = false;
if(p.length() > 1){
if(p.charAt(1) == '-' || p.length() == 2){
if(flagSet.contains(p)){
flags.add(p);
}
else{
options.put(p, ?.newInstance());
optionalParameterKey = p;
isOptionalParameter = true;
}
}
else{
for(int i = 1; i < p.length(); ++i){
flags.add("" + '-' + p.charAt(i));
}
}
}
}
else if(isOptionalParameter){
options.get(optionalParameterKey).add(p);
}
else{
params.add(p);
}
}
}
}
有什么想法吗?
答案 0 :(得分:3)
简单地说:你做不到。
如果您有.class
对象,或者您可以从中检索它的类的实例,则只能反射性地实例化Object。但是,如果您按如下方式更改方法签名:
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
然后当你调用它时添加MyStringList.class
(或任何地图值类型),你可以改变你的构造函数:
options.put(p, klass.newInstance());
您的代码应该按预期工作。
编辑:
I get this => Test.java:19: illegal start of expression
Pinput.parse(args, params, options, flags, flagSet,
ArrayList<String>.class);
ArrayList<String>
不会延伸List<String>
,ArrayList<T>
延伸List<T>
和String
延伸Object
,这意味着它有效T
。这只适用于声明为:
class MyStringList extends List<String>
泛型并不适合你想要做的事情,你真的应该把它作为你的签名:
public static void parse(String[] args, List<String> params, Map<String, List<String>> options, Set<String> flags, Set<String> flagSet)
并手动将列表实例化为ArrayList
:
options.put(arg, new ArrayList<String>());
由于List
只是一个接口,编译器知道您将提供该接口的一些实现,然后只允许您访问List
方法。