I have various classes with singleton pattern. They all are extending from an abstract class. Each class has a getInstance() method (with exact same name). I want to get instance with the class name (String). For example
public abstract class AbsCls {
}
public class A extends AbsCls {
private static A a;
private A() {
}
public synchronized static A getInstance() {
if(a==null) {
a == new A();
}
return a;
}
public class Test {
public static void main(String[] args) {
AbsCls[] array = new AbsCls[5];
array[0]=neededFunction("A");
array[1]=neededFunction("B");
}
}
All the classes have the same structure with class A. How should be the neededFunction()?
I can write "if.. else", but i feel like there should be a more elegant way. Thanks for any help in advance...
You could use the full class name as in package.ClassName
, reflection, and Class.forName(theName)
.
For instance with a String
object:
try {
String newString = (String)Class.forName("java.lang.String").newInstance();
}
catch (IllegalAccessException iae) {
// TODO handle
}
catch (InstantiationException ie) {
// TODO handle
}
catch (ClassNotFoundException cnfe) {
// TODO handle
}
So your method could roughly look like:
@SuppressWarnings("unchecked")
public static <T> T getInstance(String clazz) {
// TODO check for clazz null
try {
return (T)Class.forName(clazz).getMethod("getInstance", (Class<?>[])null).invoke(null, (Object[])null);
}
catch (ClassNotFoundException cnfe) {
// TODO handle
return null;
}
catch (NoSuchMethodException nsme) {
// TODO handle
return null;
}
catch (InvocationTargetException ite) {
// TODO handle
return null;
}
catch (IllegalAccessException iae) {
// TODO handle
return null;
}
}
Edit for OP:
The (Class<?>[])null
and (Object[])null
are null
arguments cast as their expected type.
Basically:
getMethod
method of Class
takes a String
representing the method's name, and a varargs of Class<?>
representing its parameter types. The method we call ( getInstance
) takes no arguments, therefore the argument to getMethod
is null, but we want to cast it as the expected argument. More info here . invoke
method of Method
takes an Object
as the target instance to invoke the method against (in our case, null
since it's a class method) and a varargs of Object
as the arguments. But again, your getInstance
method takes no arguments, so we use null
and cast it as an array of Object
. More info here . AbsCls[] array = new AbsCls[5]; // this create object for AbsCls
array[0]=neededFunction("A"); // calling method from AbsCls
array[1]=neededFunction("B");// calling method from AbsCls
If you create object for super class you cant get method from sub classes
AbsCls[] array = new A[5]; //this create object for A
You access both classes if you want to call super class method user super
keyword
array[0]=neededFunction("A"); //// calling method from A
array[1]=super.neededFunction("B");//// calling method from AbsCls
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.