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()) {};
}
}