If you need to instantiate a particular Java class starting from a match in the map, I would put as values builders for these classes rather than class names to be built through reflection, since it gives you better flexibility and possibly better performances.
An example of such builders:
public interface BuilderClass<O, P>{
O build(P parameter);
}
public class BuilderSpecificClass<SpecificClass, Object>{
@Override
public SpecificClass build(Object parameter){
return new SpecificClass(parameter);
}
}
Then the map would look something like:
Map<String, BuilderClass<SpecificClass, Object>> map=new HashMap<String, BuilderClass<SpecificClass, Object>>();
map.put("<class_iri>", new BuilderSpecificClass<SpecificClass, Object>());
That said, I'm not clear how your specific classes work, so there might be a better way. Can you add an example of how you built them?
Edited after Tom's extra details:
Ok, if I understand what your class is doing, you have half the approach I described already implemented.
Your class is basically wrapping sets of OWL assertion axioms, either asserted or inferred - i.e., values for your fields come either from the ontology or from a reasoner, and relate individuals with individuals or with values.
You also have methods to populate a class instance from an ontology and a reasoner; these correspond to what I proposed above as build()
method, where the parameters would be the ontology and the reasoner. You can skip passing the ontology manager since an instance of OWLOntologyManager is already accessible through the ontology: ontology.getOWLOntologyManager()
What I would do here is create builders pretty much like I described and have them call your methods to populate the objects.
In terms of performances, it's hard to tell whether there are any serious hot spots - at a guess, there shouldn't be anything particularly hard in this code. The ontology is the place where such problems usually arise.
What I can suggest in this class is the following:
private final String personURI = ThesisOntologyTools.PERSON_URI + "Person";
You have a few member variables which look like this one. I believe these are constants, so rather than having a copy in each of your instances, you might save memory by making them static final.
OWLDataProperty isLocationConfirmed = dataFactory.getOWLDataProperty(IRI.create(isLocationConfirmedURI));
You are creating a number of objects in a way similar to this. Notice that IRI.create()
will return an immutable object, as well as dataFactory.getOWLDataProperty()
, so rather than accessing the data factory each time you can reuse such objects.
All objects produced by a data factory are not linked to a specific ontology and are immutable, so you can reuse them freely across your classes, to reduce the number of new objects created. A data factory might cache some of them, but some others might be recreated from scratch on each call, so reducing the number of calls should improve speed and memory requirements.
Other than this, the approach looks fine. If the memory required or the speed are too high (or too low), you may want to start using a profiler to pinpoint the issues. and if the hotspots are in the OWL API, please raise an issue in OWLAPI issue tracker :-) we don't get enough performance reports from real users.