我在下面使用此代码,但让我先解释一下我想要实现的目标。我有3个班级,Publisher
,Consumer
和Broker
。我想创建一个静态方法,该方法从CLI接受参数,并根据我指定的内容返回每个类的列表。以下示例具有完整的功能,但仅适用于Publisher
类。我的问题是,如何修改以下代码以接受多个类并返回List< T >
而不是List< Publisher >
。我尝试使用泛型,但是这种方式无法调用构造函数来创建新的Object。不用担心String拆分,这与问题无关,主要焦点是在实例化对象的while循环内。我的目标是通过这种方式使用此类
ArgParser.< Publisher >fetchEntitiesFromCommandLine(args)
ArgParser.< Broker > fetchEntitiesFromCommandLine(args)
ArgParser.< Consumer > fetchEntitiesFromCommandLine(args)
谢谢!
public class ArgParser {
public static List<Publisher> fetchPublishersFromCommandLine(String[] args) throws IllegalArgumentException {
List<Publisher> publishers = new ArrayList<>();
int position = -1;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-p")) {
position = i;
}
}
if (position == -1)
throw new IllegalArgumentException();
try {
while (args[++position] != null) {
String[] data = args[position].split(":");
Publisher publisher = new Publisher(data[0], Integer.parseInt(data[1]));
publishers.add(publisher);
}
// This line never executes, however compiler warned me.
throw new IndexOutOfBoundsException();
} catch (IndexOutOfBoundsException err) {
return publishers;
}
}
}
答案 0 :(得分:0)
对于包含多个类型的列表,它们应该具有一个公共的超类或接口(如果您不想还原为List<Object>
)。
关于通用类型T
的新实例的实例化:您必须获取实例的具体类。如果我理解正确,则可以从运行时参数中确定具体类型。这里有两个选择
一旦解析了args并确定了具体的类型,就使用switch-case并查询每个可能的值。以下代码假定所有可能的具体类型都实现的接口Person
:
List<? extends Person> returnList = new ArrayList<>();
String personType = determinePersonTypeFromArgs(args);
Person person = null;
switch (personType) {
case "publisher" :
person = new Publisher(...);
case "bromer" :
person = new Broker(...);
case "consumer" :
person = new Consumer(...);
}
if (person != null) returnList.add(person);
return returnList;
这是一个相对简单的解决方案。但是,引入一种新型Person
要求更改代码,并且打字错误等的错误机会更大。
使用反射实例化具体的Person
。在这种情况下,字符串必须包含确切的完整类名(包括包),并且您必须根据arg类型获取构造函数。简而言之-更复杂的样板代码。但是,它更具可扩展性和弹性。