[英]Generic class that extends collection generic class
從文件中讀取LineProcessor
我正在使用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<>());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.