繁体   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