I'm having an interface "Parent", and multiple classes (say Abc.java, Def.java, and Xyz.java) implementing the interface. Now I want to do something like this:
Parent factoryMethod(String condition){
Parent p = null;
if(condition.equals("Abc"))
p = new Abc();
else if(condition.equals("Def"))
p = new Def();
else if(condition.equals("Xyz"))
p = new Xyz();
return p;
}
Basically I'm passing the name of the class to be instantiated as the parameter to the method. What is the best way to be doing this? Should I use reflection for this? Its not just 3 classes, there might be a lot more. So I don't want to write if/else.
Thanks.
One way is to define the method as a generic one, with a type parameter extending Parent
, and then create the instance by reflection:
<T extends Parent> T factoryMethod(Class<T> clazz) throws Exception {
return (T) clazz.newInstance();
}
You can then use the method as follows:
Abc abc = obj.factoryMethod(Abc.class);
Def def = obj.factoryMethod(Def.class);
// The below won't compile if SomeOtherClass does not implement Parent
SomeOtherClass instance = obj.factoryMethod(SomeOtherClass.class);
However this assumes that all subclasses of Parent
have no-argument constructor (either they define a no-argument constructor or they don't define any constructor, hence having a default constructor available).
You could use an enum to implement a strategy pattern like so:
public enum ParentFactory {
Abc(Abc.class),
Def(Def.class),
Xyz(Xyz.class);
private Class<? extends Parent> childClass;
private ParentFactory(Class<? extends Parent> childClass) {
this.childClass = childClass;
}
public <T extends List> T getParentInstance() throws InstantiationException, IllegalAccessException {
return (T) childClass.newInstance();
}
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
ParentFactory parentFactory = ParentFactory.valueOf("Abc");
Parent parent = parentFactory.getParentInstance();
}
You can chose the constructor to be used on the basis of the name of the class you are trying to create an object for. Something like:
Class<?> theClass = Class.forName(condition); Constructor<?> theClassConstructor = theClass.getConstructor(); Object object = theClassConstructor.newInstance(new Object[] { args });
If you know the full class name, you could use the Reflection API like this :
try {
return Class.forName(condition).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
// do something with exception
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.