Hope you can help me with this: I have ...
classNameList
Geography<T>
<T> void read(Class<T> cl, Geography<T> geo)
I want to loop through the string class name list and call the generic method for each of these classes.
What I tried but obviously did not work:
for (int i = 0; i < classNameList.length; i++) {
Class<?> myClass = Class.forName(classNameList[i].getName());
Geography<myClass.newInstance()> geo;
read(myClass, geo);
}
Error: myClass.newInstance cannot be resolved to a type
My code runs perfectly for a single call of the generic function:
Geography<ExampleClass> ExampleGeo;
read(ExampleClass.class, ExampleGeo);
Any ideas how I could do this?
UPDATE:
Thanks for the helpful input, still it's hard for me to adopt it to my real code. So this is the non simplyfied problem:
I do ready in shapefile-Data with a shapefileLoader, for each feature of the Shapefile a class (GuadAgent) is initialized with a predifined class (PlantWind). I have shapefiles in my input-directory with the names of the Classes their features do represent. I want Java to read in the shapefiles and create the respective agent class. (the agents are also placed in a context and a geography..) Used classes are: ShapefileLoader, Geography, the other classes can be find at the same website
This part is in the main-method:
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();
}
}
The static Method that reads in the names:
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;
}
How can I get rid of the switch? Although their number is finit, there are very many different agents...
Unfortunately, there's no syntax close to your intention (nice idea though).
The basic problem is that Class.forName()
returns an unknown Class<?>
, so you need a cast somewhere. It's just a mater of where you put it.
I suggest this approach (which compiles) that bundles up doing a read()
based on a class name:
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);
}
May I also suggest using the foreach loop syntax, for tidier code:
for (String className : classNameList) {
readForName(className.getName());
}