检查T的实例并有条件地调用相应的构造函数

时间:2019-04-20 11:47:05

标签: java oop object

我在下面使用此代码,但让我先解释一下我想要实现的目标。我有3个班级,PublisherConsumerBroker。我想创建一个静态方法,该方法从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;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

对于包含多个类型的列表,它们应该具有一个公共的超类或接口(如果您不想还原为List<Object>)。
关于通用类型T的新实例的实例化:您必须获取实例的具体类。如果我理解正确,则可以从运行时参数中确定具体类型。这里有两个选择

  1. 一旦解析了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要求更改代码,并且打字错误等的错误机会更大。

  2. 使用反射实例化具体的Person。在这种情况下,字符串必须包含确切的完整类名(包括包),并且您必须根据arg类型获取构造函数。简而言之-更复杂的样板代码。但是,它更具可扩展性和弹性。