簡體   English   中英

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

[英]Java - Generic List of Generic Abstract Classes

我正在使用一個包含抽象的通用Parsable類的庫:

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

通過子類化,此類允許用戶從字符串創建類型的實例。 我發現自己不得不解析對象列表。 例如,可能存在一個IntParser extends Parsable<Integer>而我想實現一個IntListParser extends Parsable<List<Integer>> 這可以很簡單地完成:

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;
  }
}

對於每種類型的解析器,都可以成功完成此操作。 在此示例中,關於整數沒有什么特別的。 在編寫了幾個相同的類之后,我決定是時候創建一個泛型來執行此操作了:

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;
  }
}

不幸的是,這不起作用,因為new TParser()命令無法編譯。 有什么辦法可以解決這個問題,還是我必須為每種解析器類型創建此代碼的新副本?

我嘗試過的無效解決方案是:

  • 使解析靜態。 這樣可以避免必須創建Parsables實例,但是由於您無法創建抽象靜態函數,因此無法正常工作。
  • GenericListParser<TParser extends Parsable<T>>擴展Parsable<T>而不是Parsable<List<T>> 這將允許其parse函數調用Parsable<T>的parse函數,因為它是其自身的超級。 這不起作用,因為解析的返回類型為T並且您無法將List<T>T

與其嘗試為未知內容創建解析器,不如將其接受為參數:

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;
  }
}

我認為您的方法是不正確的方法,應該刪除所有列表解析類,並使用一個類型化的靜態實用程序方法來替換它們以及新的“通用”類:

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;
}

現在您可以這樣稱呼它:

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

如果每個列表解析器都需要單獨的類,則:

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;
    }
}

然后使用:

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