简体   繁体   English

扩展集合泛型类的泛型类

[英]Generic class that extends collection generic class

I'm using Guava's LineProcessor interface when reading lines from files. 从文件中读取LineProcessor我正在使用Guava的LineProcessor接口。 I've created my class called Line Loader which will store lines read. 我创建了名为Line Loader类,该类将存储读取的行。 I want it to be generic on choice of collection lines should be stored in so I wrote something like this: 我希望它在选择收集行时是通用的,因此我写了这样的内容:

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

where with init() method I force subclasses to chose type of collection, for example: 在哪里使用init()方法强制子类选择集合的类型,例如:

public abstract class LinkedLineLoader<T> extends LineLoader<T> {
    @Override
    protected Collection<T> init() {
        return new LinkedList<T>();
    }
}

I planned on doing this: 我计划这样做:

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;
    }
}

so that latter subclases (if needed) could do: 这样后面的子分类(如果需要)可以:

public class LinkedLineLoader<T> extends LineLoader<LinkedList<T>> {

}

but it's not possible. 但这是不可能的。 Is there a clean solution to this problem? 有没有解决这个问题的解决方案?

In Java it is not possible to create instances from generic type arguments, because generics are erased at run-time. 在Java中,无法从泛型类型参数创建实例,因为泛型会在运行时删除。 Also, generic type arguments can not themselves declare additional type arguments like C<T> . 同样,泛型类型参数本身不能声明其他类型参数,例如C<T> Therefore the code you posted is entirely illegal and will not compile: 因此,您发布的代码完全是非法的,并且不会编译:

private final C<T> result; // illegal
result = new C<T>(); // illegal

Aside from that, your declaration of the type arguments itself has some flaws. 除此之外,您对类型实参的声明本身还有一些缺陷。 The following code is no legal Java code: 以下代码不是合法的Java代码:

public class LineLoader<T> implements LineProcessor<C<T> extends Collection<T>>

It should actually look eg like this: 它实际上应该看起来像这样:

public class LineLoader<T, C extends Collection<T>> implements LineProcessor<C>

As a solution to your problem, you could declare your LineLoader as shown above, and add a protected constructor, that takes the generic collection as an argument: 为了解决您的问题,您可以如上所示声明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;
    }
}

Then you can implement your LinkedLineLoader like so: 然后,您可以像这样实现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