2014-03-26 78 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<>()); 
    } 
}