[英]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: 我尝试过的无效解决方案是:
Parsables
but it doesn't work because you can't make abstract static functions. Parsables
实例,但是由于您无法创建抽象静态函数,因此无法正常工作。 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.