我正在使用包含抽象通用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;
}
}
这可以针对每种类型的解析器成功完成。在这个例子中,Integer没有什么特别之处。在写了几个相同的类后,我决定是时候创建一个通用的了:
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()
没有编译。有没有办法解决这个问题,或者我是否被迫为每种类型的Parser创建此代码的新副本?
我尝试过的解决方案是:
Parsables
的实例,但它不起作用,因为您无法创建抽象的静态函数。GenericListParser<TParser extends Parsable<T>>
延长Parsable<T>
而不是Parsable<List<T>>
。这将允许其parse
函数调用Parsable<T>
的解析函数,因为它是它自己的超级函数。这不起作用,因为解析的返回类型为T
,您无法将List<T>
转换为T
。答案 0 :(得分:4)
不是试图为未知的东西创建解析器,而是将其作为参数接受:
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;
}
}
答案 1 :(得分:2)
我认为您的方法不是正确的方法,您应该删除所有列表解析类并替换它们,以及新的&#34;泛型&#34; class,使用单一类型的静态实用程序方法:
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());
}
}