有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

扩展集合泛型类的java泛型类

我在从文件中读取行时使用Guava's ^{}接口。我已经创建了名为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>> {

}

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


共 (1) 个答案

  1. # 1 楼答案

    在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<>());
        }
    }