首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展集合泛型类的泛型类。

扩展集合泛型类的泛型类。
EN

Stack Overflow用户
提问于 2014-03-26 05:50:55
回答 1查看 833关注 0票数 0

我在从文件中读取行时使用LineProcessor接口。我创建了名为Line Loader的类,它将存储读过的行。我希望它在选择集合行时是通用的,应该存储在其中,所以我写了如下所示:

代码语言:javascript
复制
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()方法,我强制子类选择集合类型,例如:

代码语言:javascript
复制
public abstract class LinkedLineLoader<T> extends LineLoader<T> {
    @Override
    protected Collection<T> init() {
        return new LinkedList<T>();
    }
}

我打算这么做:

代码语言:javascript
复制
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;
    }
}

这样后一个子类(如果需要的话)可以做到:

代码语言:javascript
复制
public class LinkedLineLoader<T> extends LineLoader<LinkedList<T>> {

}

但这不可能。这个问题有干净的解决办法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-26 07:43:52

在Java中,不可能从泛型类型参数创建实例,因为泛型在运行时被擦除。此外,泛型类型参数本身不能声明其他类型参数,如C<T>。因此,您发布的代码是完全非法的,不会编译:

代码语言:javascript
复制
private final C<T> result; // illegal
result = new C<T>(); // illegal

除此之外,类型参数的声明本身也有一些缺陷。以下代码不是合法的Java代码:

代码语言:javascript
复制
public class LineLoader<T> implements LineProcessor<C<T> extends Collection<T>>

实际上,它应该是这样的:

代码语言:javascript
复制
public class LineLoader<T, C extends Collection<T>> implements LineProcessor<C>

作为解决问题的方法,您可以如前所述声明您的LineLoader,并添加一个受保护的构造函数,该构造函数将泛型集合作为参数:

代码语言:javascript
复制
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

代码语言:javascript
复制
class LinkedLineLoader<T> extends LineLoader<T, LinkedList<T>> {
    public LinkedLineLoader() {
        super(new LinkedList<>());
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22652546

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档