[英]Instantiate Java anonymous inner class with generic using Class in variable
[英]Instantiate a generic variable using string class name
我正在使用谷歌的CSVReader,它需要一個類名來創建一個解析器。 使用解析器,我正在將CSV文件讀入列表。
考慮以下代碼:
ValueProcessorProvider provider = new ValueProcessorProvider();
CSVEntryParser<A> entryParser = new AnnotationEntryParser<A>(A.class, provider);
CSVReader<A> newExternalFileCSVReader =
new CSVReaderBuilder<A>(m_NewExternalFile).entryParser((CSVEntryParser<A>) entryParser).strategy(new CSVStrategy(',', '"', '#', true, true)).build();
List<A> m_NewExternalFileData = newExternalFileCSVReader.readAll();
使用此代碼,我可以讀取特定於A類的CSV文件。
我還有其他幾個類:B,C,D,它們都使用上面相同的代碼,只是它們各自的類。
可以有一個函數,我將類名稱作為String傳遞,它可以根據String輸入名稱實例化CSVReader /解析器嗎? 而不是必須創建3個不同的代碼段(對於類B,C,D),我可以使用相同的一個,只需輸入相關的類名?
您可以使用工廠模式。
創建一個接口並在A,B,C和D的基本方法內定義。
然后所有A,B,C和D類都必須實現該接口。
public interface BaseInterface {
// your methods
}
然后創建一個Factory類,在該類中傳遞一個標識符,它將使您的閱讀器正確啟動
package a;
public final class Factory {
// Not instantiable
private Factory() {
throw new AssertionError("Not instantiable");
}
public static CSVReader<your interface> getReader(String reader) {
if ("A".equals(reader)) {
return new CSVReader<A>();
} else if ("B".equals(reader)) {
return new CSVReader<B>();
}
// TODO create all your readers
}
}
現在,您可以通過您的工廠類呼叫讀者,如下所示:
ValueProcessorProvider provider = new ValueProcessorProvider();
CSVEntryParser<A> entryParser = new AnnotationEntryParser<A>(A.class, provider);
CSVReader<your interface> newExternalFileCSVReader =
Factory("your reader type");
List<your interface> m_NewExternalFileData = newExternalFileCSVReader.readAll();
由於你沒有發布A,B,C和D類,你必須自定義該代碼,但按照這種方式,我認為你可以完成你想要的。
你可以這樣做:
public class MyCSVReader<T> {
private Class<T> clazz;
public MyCSVReader(Class<T> clazz) {
this.clazz = clazz;
}
public List<T> readData(File file) {
ValueProcessorProvider provider = new ValueProcessorProvider();
CSVEntryParser<T> parser = new AnnotationEntryParser<T>(clazz, provider);
CSVStrategy strategy = new CSVStrategy(',', '"', '#', true, true);
CSVReaderBuilder builder = new CSVReaderBuilder<T>(file);
CSVReader<T> reader = builder.entryParser(parser ).strategy(strategy).build();
return reader.readAll();
}
}
然后你會做:
MyCSVReader<A> readerA = new MyCSVReader<>(A.class);
List<A> data = readerA.readData(m_NewExternalFile);
對於任何其他課程也一樣。
編輯:也許通過文件擴展名查找類型會有用嗎?
public class MyCSVReaderFactory {
private static Map<String, MyCSVReader<?>> readersByFileExtension = new HashMap<>();
// files with data for class A have extension .xta, etc.
static {
readersByFileExtension.put(".xta", new MyCSVReader<>(A.class));
readersByFileExtension.put(".xtb", new MyCSVReader<>(B.class));
}
public MyCSVReader<?> create(String fileExtension) {
MyCSVReader<?> reader = readersByFileExtension.get(fileExtension);
if (reader == null) {
throw new IllegalArgumentException("Unknown extension: " + fileExtension);
}
return reader;
}
}
public List<?> doStuff(File file) {
String fileExtension = getFileExtension(file);
MyCSVReader<?> reader = MyCSVReaderFactory.create(fileExtension);
return reader.readAll();
}
private String getFileExtension(File file) {
// TODO: implement this
}
如果您不需要List(對象),則AD類應實現公共接口或擴展可用於概括的公共超類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.