我在从文件中读取行时使用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>> {
}但这不可能。这个问题有干净的解决办法吗?
发布于 2014-03-26 07:43:52
在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<>());
}
}https://stackoverflow.com/questions/22652546
复制相似问题