Java 使用字符串类名称的泛型类型调用

Java 使用字符串类名称的泛型类型调用,java,generics,shapefile,geotools,repast-simphony,Java,Generics,Shapefile,Geotools,Repast Simphony,希望您能在这方面帮助我: 我有 名为classNameList 通用类Geography 静态通用方法无效读取(类别cl,地理地理位置) 我想遍历字符串类名列表,并为每个类调用泛型方法 我尝试过但显然不起作用: for (int i = 0; i < classNameList.length; i++) { Class<?> myClass = Class.forName(classNameList[i].getName()); Geography<myC

希望您能在这方面帮助我: 我有

  • 名为
    classNameList
  • 通用类
    Geography
  • 静态通用方法
    无效读取(类别cl,地理地理位置)
我想遍历字符串类名列表,并为每个类调用泛型方法

我尝试过但显然不起作用:

for (int i = 0; i < classNameList.length; i++) {
   Class<?> myClass = Class.forName(classNameList[i].getName());
   Geography<myClass.newInstance()> geo;
   read(myClass, geo);
}
for(int i=0;i
错误:myClass.newInstance无法解析为类型

我的代码只需调用一次泛型函数即可完美运行:

Geography<ExampleClass> ExampleGeo;
read(ExampleClass.class, ExampleGeo);
地理示例geo;
阅读(ExampleClass.class,ExampleGeo);
你知道我该怎么做吗

更新:

感谢您的帮助,但我还是很难将其应用到我的实际代码中。 这是一个非简化的问题:

我使用shapefileLoader在shapefile数据中做了准备,对于shapefile的每个特性,一个类(GuadAgent)用一个预定义的类(PlantWind)初始化。在我的输入目录中有shapefile,其中包含它们的特性所代表的类的名称。我希望Java读入shapefile并创建相应的代理类。(代理也放置在上下文和地理位置中…) 使用的类为:,其他类可在同一网站上找到

本部分主要采用以下方法:

Geography<GuadAgent> guadGeography = GeographyFactoryFinder.createGeographyFactory(null).createGeography("guadGeography", context, new GeographyParameters<GuadAgent>());
Context<GuadAgent> context = new DefaultContext<GuadAgent>();

FileFilter filter = new FileFilter() {
    @Override
    public boolean accept(File file) {
        return file.getName().endsWith(".shp"); // return .shp files
    }
};
String shapefileDir = System.getProperty("user.dir")+"\\input\\shp\\";
File folder = new File(shapefileDir);
File[] listOfFiles = folder.listFiles(filter);

for (File classFile : listOfFiles) {
        try {
            readForName(classFile,context,guadGeography);
        } catch (ClassNotFoundException | MalformedURLException
                | FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}
Geography-guadGeography=GeographyFactoryFinder.createGeographyFactory(null).createGeography(“guadGeography”,context,new GeographyParameters());
Context Context=新的DefaultContext();
FileFilter=newfilefilter(){
@凌驾
公共布尔接受(文件){
return file.getName().endsWith(“.shp”);//return.shp文件
}
};
字符串shapefileDir=System.getProperty(“user.dir”)+“\\input\\shp\\”;
文件夹=新文件(shapefileDir);
File[]listOfFiles=folder.listFiles(过滤器);
对于(文件类文件:listOfFiles){
试一试{
readForName(类文件、上下文、语法);
}catch(ClassNotFoundException | MalformedUrlexException
|FileNotFounde(异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
读取名称的静态方法:

static <T> void readForName(File classFile, Context<GuadAgent> context,Geography<GuadAgent> guadGeography) throws ClassNotFoundException, MalformedURLException, FileNotFoundException {

        String shapefileDir = System.getProperty("user.dir")+"\\input\\shp\\";
        String className = classFile.getName().split("\\.(?=[^\\.]+$)")[0];
        File shapefile = null;
        shapefile = new File(shapefileDir+classFile.getName());

        if (!shapefile.exists()) {
            throw new FileNotFoundException("Could not find the given shapefile: " + shapefile.getAbsolutePath());
        }

        switch (className) {
        case "PlantWind":           
            ShapefileLoader<PlantWind> PlantWindLoader = new ShapefileLoader<PlantWind>(PlantWind.class,shapefile.toURI().toURL() , guadGeography, context);
            PlantWindLoader.load();
            PlantWindLoader.close();
            System.out.println(context.getObjects(PlantWind.class).size());                     
            break;
    // Todo Add other Agent types
    default:
        break;
    }
static void readForName(文件类文件、上下文上下文、地理记录)抛出ClassNotFoundException、MalformedURLException、FileNotFoundException{
字符串shapefileDir=System.getProperty(“user.dir”)+“\\input\\shp\\”;
字符串className=classFile.getName().split(“\\.(?=[^\\.]+$)”)0];
文件shapefile=null;
shapefile=新文件(shapefileDir+classFile.getName());
如果(!shapefile.exists()){
抛出新的FileNotFoundException(“找不到给定的shapefile:+shapefile.getAbsolutePath());
}
开关(类名){
案例“PlantWind”:
ShapefileLoader PlantWindLoader=新的ShapefileLoader(PlantWind.class,shapefile.toURI().toURI(),guadGeography,context);
PlantWindLoader.load();
PlantWindLoader.close();
System.out.println(context.getObjects(PlantWind.class.size());
打破
//Todo添加其他代理类型
违约:
打破
}

如何摆脱开关?虽然它们的数量有限,但有很多不同的代理…

您可以在Geography(或任何其他类)中创建静态工厂方法:

公共静态地理实例(类cls)
抛出反射操作异常{
返回新的地理位置(cls.newInstance());
}
我猜测了Geography类的构造函数。如果我猜错了,请编辑您的问题,将构造函数包含在Geography中


您可以在Geography(或任何其他类)中创建静态工厂方法:

公共静态地理实例(类cls)
抛出反射操作异常{
返回新的地理位置(cls.newInstance());
}
我猜测了Geography类的构造函数。如果我猜错了,请编辑您的问题,将构造函数包含在Geography中

更新:我不确定Geography类要做什么。如果它需要一个泛型对象,它可能如下所示:

public class Geography<T> {
    private final T data;

    public Geography(T data) {
        this.data = Objects.requireNonNull(data);
    }
}
public class Geography<T> {
    private final Class<T> dataClass;

    public Geography(Class<T> cls) {
        this.dataClass = Objects.requireNonNull(cls);
    }
}
公共课地理{
私有最终T数据;
公共地理(T数据){
this.data=Objects.requirennull(数据);
}
}
如果它需要一个类,构造函数可能如下所示:

public class Geography<T> {
    private final T data;

    public Geography(T data) {
        this.data = Objects.requireNonNull(data);
    }
}
public class Geography<T> {
    private final Class<T> dataClass;

    public Geography(Class<T> cls) {
        this.dataClass = Objects.requireNonNull(cls);
    }
}
公共课地理{
私有最终类数据类;
公共地理(cls类){
this.dataClass=Objects.requirennull(cls);
}
}

不幸的是,没有与您的意图相近的语法(尽管这是个好主意)

基本问题是
Class.forName()
返回一个未知的
Class
,因此您需要在某个地方进行强制转换。这只是您将其放置在何处的问题

我建议使用这种方法(编译),根据类名捆绑执行
read()

static <T> void readForName(String className) throws ClassNotFoundException {
    Class<T> myClass = (Class<T>) Class.forName(className);
    Geography<T> geo = new Geography<T>();  // No code shown. Adjust as required
    read(myClass, geo);
}
在运行时从泛型类型创建实例 我不完全清楚你想实现什么,但乍看起来,最简单的解决方案就是最好的解决方案

可以通过使用脚本环境(Groovy、JavaScript、JRuby、Jython)来解决这个问题,该环境可以动态地评估和执行任意代码来创建对象,但仅仅创建一个对象就变得极其复杂

但不幸的是,我认为它有一个非常简单的解决方案

只要有一组预定义的支持类型,就可以使用
工厂
模式
for (String className : classNameList) {
    readForName(className.getName());
}
public class Q26289147_ProviderPattern
{
    private static final List<String> CLASS_NAMES = ImmutableList.of("String", "Integer", "Boolean");
    private static final Map<String, Provider<StrawManParameterizedClass>> PROVIDERS;

    static
    {
        final ImmutableMap.Builder<String, Provider<StrawManParameterizedClass>> imb = ImmutableMap.builder();
        for (final String cn : CLASS_NAMES)
        {
            switch (cn)
            {
                case "String":
                    imb.put(cn, new Provider<StrawManParameterizedClass>()
                    {
                        @Override
                        public StrawManParameterizedClass<String> get() { return new StrawManParameterizedClass<String>() {}; }
                    });
                    break;
                case "Integer":
                    imb.put(cn, new Provider<StrawManParameterizedClass>()
                    {
                        @Override
                        public StrawManParameterizedClass<Integer> get() { return new StrawManParameterizedClass<Integer>() {}; }
                    });
                    break;
                case "Boolean":
                    imb.put(cn, new Provider<StrawManParameterizedClass>()
                    {
                        @Override
                        public StrawManParameterizedClass<Integer> get() { return new StrawManParameterizedClass<Integer>() {}; }
                    });
                    break;
                default:
                    throw new IllegalArgumentException(String.format("%s is not a supported type %s", cn, Joiner.on(",").join(CLASS_NAMES)));
            }
        }
        PROVIDERS = imb.build();
    }

    static <T> void read(@Nonnull final StrawManParameterizedClass<T> smpc) { System.out.println(smpc.type.toString()); }

    static abstract class StrawManParameterizedClass<T>
    {
        final TypeToken<T> type = new TypeToken<T>(getClass()) {};

        @Override
        public String toString() { return type.getRawType().getCanonicalName(); }
    }

    public static void main(final String[] args)
    {
        for (final String cn : CLASS_NAMES)
        {
            read(PROVIDERS.get(cn).get());
        }
    }
}
import com.google.common.reflect.TypeToken;

public class Q26289147
{
    public static void main(final String[] args) throws IllegalAccessException, InstantiationException
    {
        final StrawManParameterizedClass<String> smpc = new StrawManParameterizedClass<String>() {};
        final String string = (String) smpc.type.getRawType().newInstance();
        System.out.format("string = \"%s\"",string);
    }

    static abstract class StrawManParameterizedClass<T>
    {
        final TypeToken<T> type = new TypeToken<T>(getClass()) {};
    }
}