2014-03-26 39 views
0

从文件读取行时,我使用的是Guava's LineProcessor接口。我创建了我的课,名为Line Loader,它将存储读取的行。我想这是通用在收线的选择应存放在我这么写是这样的:扩展集合通用类的通用类

其中具有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; 
    } 
} 

使后者subclases(如果需要的话)可以这样做:

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

} 

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

回答

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