简体   繁体   English

Java-通用抽象类的通用列表

[英]Java - Generic List of Generic Abstract Classes

I am using a library that contains an abstract generic Parsable class: 我正在使用一个包含抽象的通用Parsable类的库:

public abstract class Parsable<T> {
  T parse(String s);
}

By subclassing this class allows users to create instances of types from Strings. 通过子类化,此类允许用户从字符串创建类型的实例。 I find myself having to parse lists of objects. 我发现自己不得不解析对象列表。 For instance there could exist a IntParser extends Parsable<Integer> and I want to implement an IntListParser extends Parsable<List<Integer>> . 例如,可能存在一个IntParser extends Parsable<Integer>而我想实现一个IntListParser extends Parsable<List<Integer>> This can be done pretty straightforwardly: 这可以很简单地完成:

public class IntListParser extends Parsable<List<Integer>> {
  List<Integer> parse(String s) {
    IntParser ip = new IntParser();
    String[] strings = s.split(",");
    List<Integer> result;
    for (String s : strings) {
      result.add(ip.parse(s));
    }
    return result;
  }
}

This can be done successfully for every type of parser. 对于每种类型的解析器,都可以成功完成此操作。 There is nothing special about an Integer in this example. 在此示例中,关于整数没有什么特别的。 After writing several of these identical classes I decided it was time to create a generic to do this: 在编写了几个相同的类之后,我决定是时候创建一个泛型来执行此操作了:

public class GenericListParser<TParser extends Parsable<T>> extends Parsable<List<T>> {
  List<T> parse(String s) {
    TParser tp = new TParser();
    String[] strings = s.split(",");
    List<T> result;
    for (String s : strings) {
      result.add(tp.parse(s));
    }
    return result;
  }
}

Unfortunately this doesn't work because the command new TParser() doesn't compile. 不幸的是,这不起作用,因为new TParser()命令无法编译。 Is there any way to get around this or am I forced to create a new copy of this code for every type of Parser? 有什么办法可以解决这个问题,还是我必须为每种解析器类型创建此代码的新副本?

The solutions that I tried that didn't work are: 我尝试过的无效解决方案是:

  • Making parse static. 使解析静态。 This would prevent having to create instances of the Parsables but it doesn't work because you can't make abstract static functions. 这样可以避免必须创建Parsables实例,但是由于您无法创建抽象静态函数,因此无法正常工作。
  • Have GenericListParser<TParser extends Parsable<T>> extend Parsable<T> instead of Parsable<List<T>> . GenericListParser<TParser extends Parsable<T>>扩展Parsable<T>而不是Parsable<List<T>> This would allow its parse function to call Parsable<T> 's parse function because it is its own super. 这将允许其parse函数调用Parsable<T>的parse函数,因为它是其自身的超级。 This doesn't work because the return type of parse is T and you can't cast List<T> to T . 这不起作用,因为解析的返回类型为T并且您无法将List<T>T

Rather than trying to create a parser for something unknown, accept it as a parameter: 与其尝试为未知内容创建解析器,不如将其接受为参数:

public class GenericListParser<TParser extends Parsable<T>> extends Parsable<List<T>> {
  private TParser tp = null;
  public GenericListParser(TParser parser) {
      this.tp = parser;
  }
  List<T> parse(String s) {
    String[] strings = s.split(",");
    List<T> result;
    for (String s : strings) {
      result.add(tp.parse(s));
    }
    return result;
  }
}

I think your approach is not the right way and that you should delete all your list parsing classes and replace them, and your new "generic" class, with a single typed static utility method: 我认为您的方法是不正确的方法,应该删除所有列表解析类,并使用一个类型化的静态实用程序方法来替换它们以及新的“通用”类:

public ststic <T> List<T> parseList(String s, Parsable<T> p) {
    List<T> result = new ArrayList<>();
    for (String s : s.split(","))
        result.add(p.parse(s));
    return result;
}

Now you can call it like this: 现在您可以这样称呼它:

List<Integer> ints = parseList("1,2,3", new IntParser());

If you need separate classes for each list parser, then: 如果每个列表解析器都需要单独的类,则:

public abstract class ListParser<T> extends Parsable<List<T>> {
    private final Parsable<T> Parsable;
    protected ListParser(Parsable<T> p) {
        parsable = p;
    }
    public List<T> parse(String s) {
        List<T> result = new ArrayList<>();
        for (String s : s.split(","))
            result.add(parsable.parse(s));
        return result;
    }
}

Then to use: 然后使用:

public class IntListParser extends ListParser<Integer> {
    public IntListParser() {
        super(new IntParser());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM