从文件中读取行时,我正在使用Guava的LineProcessor
界面。我已经创建了名为的类,该类Line Loader
将存储读取的行。我希望它在选择收集行时是通用的,因此我写了这样的内容:
public abstract class LineLoader<T> implements LineProcessor<Collection<T>> {
private final Collection<T> result;
public LineLoader() {
this.result = init();
}
protected boolean add(final T line) {
return result.add(line);
}
@Override
public boolean processLine(final String line) throws Exception {
final T data = parser.parseLine(line);
if (data == null) {
return false;
}
return add(data);
}
@Override
public Collection<T> getResult() {
return result;
}
protected abstract Collection<T> init();
}
init()
我在哪里用方法强制子类选择集合的类型,例如:
public abstract class LinkedLineLoader<T> extends LineLoader<T> {
@Override
protected Collection<T> init() {
return new LinkedList<T>();
}
}
我计划这样做:
public class LineLoader<T> implements LineProcessor<C<T> extends Collection<T>> {
private final C<T> result;
public LineLoader() {
result = new C<T>();
}
protected boolean add(final T line) {
return result.add(line);
}
@Override
public boolean processLine(final String line) throws Exception {
final T data = parser.parseLine(line);
if (data == null) {
return false;
}
return add(data);
}
@Override
public C<T> getResult() {
return result;
}
}
这样后面的子分类(如果需要)可以:
public class LinkedLineLoader<T> extends LineLoader<LinkedList<T>> {
}
但这是不可能的。有没有解决这个问题的解决方案?
在Java中,无法从泛型类型参数创建实例,因为泛型会在运行时删除。同样,泛型类型参数本身不能声明其他类型参数,例如C<T>
。因此,您发布的代码完全是非法的,并且不会编译:
private final C<T> result; // illegal
result = new C<T>(); // illegal
除此之外,类型参数本身的声明还有一些缺陷。以下代码不是合法的Java代码:
public class LineLoader<T> implements LineProcessor<C<T> extends Collection<T>>
它实际上应该看起来像这样:
public class LineLoader<T, C extends Collection<T>> implements LineProcessor<C>
作为解决问题的方法,您可以LineLoader
如上所示声明,并添加一个受保护的构造函数,该构造函数将通用集合作为参数:
public abstract class LineLoader<T, C extends Collection<T>> implements LineProcessor<C> {
private final C result;
protected LineLoader(C collection) {
result = collection;
}
protected boolean add(final T line) {
return result.add(line);
}
@Override
public boolean processLine(final String line) throws IOException {
final T data = parser.parseLine(line);
if (data == null) {
return false;
}
return add(data);
}
@Override
public C getResult() {
return result;
}
}
然后,您可以LinkedLineLoader
像这样实现您的:
class LinkedLineLoader<T> extends LineLoader<T, LinkedList<T>> {
public LinkedLineLoader() {
super(new LinkedList<>());
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句