簡體   English   中英

擴展集合泛型類的泛型類

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM