使用字符串类名实例化泛型变量

时间:2015-11-26 09:33:15

标签: java csv generics

我使用谷歌的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传递,可以根据字符串输入名称实例化CSVReader /解析器?而不是必须创建3个不同的代码段(对于类B,C,D),我可以使用相同的一个,只需输入相关的类名吗?

2 个答案:

答案 0 :(得分:4)

您可以使用工厂模式。

创建一个接口并在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类,您必须自定义该代码,但按照这种方式,我认为您可以完成您想要的任务。

答案 1 :(得分:4)

你可以这样做:

    protected override void OnResume()
    {
        base.OnResume();

        //Here you would read it from where ever.
        var userSelectedCulture = new CultureInfo("en-US");
        Thread.CurrentThread.CurrentCulture = userSelectedCulture;
    }

然后你会这样做:

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

如果你不想要一个List(对象),那么A-D类应该实现一个公共接口或扩展一个可用于概括的公共超类。