Java 使用字符串类名实例化泛型变量
我正在使用google的CSVReader,它需要一个类名来创建解析器。使用解析器,我将CSV文件读入列表 考虑以下代码:Java 使用字符串类名实例化泛型变量,java,csv,generics,Java,Csv,Generics,我正在使用google的CSVReader,它需要一个类名来创建解析器。使用解析器,我将CSV文件读入列表 考虑以下代码: ValueProcessorProvider provider = new ValueProcessorProvider(); CSVEntryParser<A> entryParser = new AnnotationEntryParser<A>(A.class, provider); CSVReader<A> new
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();
ValueProcessorProvider提供程序=新的ValueProcessorProvider();
CSVEntryParser entryParser=newannotationentryparser(A.class,provider);
CSVReader新外部文件CSVReader=
新建CSVReaderBuilder(m_NewExternalFile).entryParser((CSVEntryParser)entryParser).strategy(新建CSVStrategy(‘,‘,‘,‘,‘,‘,‘,‘,‘,‘,‘,’,true)).build();
List m_NewExternalFileData=newExternalFileCSVReader.readAll();
使用此代码,我可以读取特定于a类的CSV文件。我还有其他几个类:B、C、D,它们都使用上面相同的代码,只是使用它们各自的类
是否有一个函数,我将类名作为字符串传递,它可以基于字符串输入名实例化CSVReader/解析器?在这个函数中,我不必创建3个不同的代码段(对于类B、C、D),而可以使用相同的代码段,只需输入相关的类名?您可以使用工厂模式 创建一个接口并在A、B、C和D的基本方法内部定义 然后所有A、B、C和D类都必须实现该接口
public interface BaseInterface {
// your methods
}
然后创建一个工厂类,在其中传递一个标识符,它将返回正确启动的读取器
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
}
}
a包;
公共末级工厂{
//不可实例化
私人工厂(){
抛出新断言错误(“不可实例化”);
}
公共静态CSVReader getReader(字符串读取器){
如果(“A”。等于(读卡器)){
返回新的CSVReader();
}否则,如果(“B”。等于(读卡器)){
返回新的CSVReader();
}
//要创建所有的读者吗
}
}
现在,您可以通过factory类调用阅读器,如下所示:
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();
ValueProcessorProvider提供程序=新的ValueProcessorProvider();
CSVEntryParser entryParser=newannotationentryparser(A.class,provider);
CSVReader新外部文件CSVReader=
工厂(“您的阅读器类型”);
List 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{
私人课堂;
公共MyCSVReader(clazz类){
this.clazz=clazz;
}
公共列表读取数据(文件){
ValueProcessorProvider提供程序=新的ValueProcessorProvider();
CSVEntryParser parser=newannotationentryparser(clazz,provider);
CSVStrategy strategy=新CSVStrategy(“,”,“,”,“#”,true,true);
CSVReaderBuilder=新CSVReaderBuilder(文件);
CSVReader reader=builder.entryParser(parser).strategy(strategy.build();
返回reader.readAll();
}
}
然后你会做:
MyCSVReader<A> readerA = new MyCSVReader<>(A.class);
List<A> data = readerA.readData(m_NewExternalFile);
MyCSVReader readerA=新的MyCSVReader(A.class);
List 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
}
公共类MyCSVReaderFactory{
私有静态映射创建(字符串文件扩展名){
MyCSVReader reader=readersByFileExtension.get(fileExtension);
如果(读卡器==null){
抛出新的IllegalArgumentException(“未知扩展名:“+fileExtension”);
}
返回读取器;
}
}
公共列表文件(文件){
字符串fileExtension=getFileExtension(文件);
MyCSVReader reader=MyCSVReaderFactory.create(文件扩展名);
返回reader.readAll();
}
私有字符串getFileExtension(文件名){
//TODO:实现这一点
}
如果您不想要一个列表(对象),那么类a-D应该实现一个公共接口或扩展一个可用于泛化的公共超类。a、B、C和D是否以任何方式相关或类似?我认为您没有纠正以下代码,CSVReaderBuilder builder=new CSVReaderBuilder(file)//它仍然是指类AIf如果这回答了你的问题,请接受答案。