使用类名调用来自不同类的方法

时间:2013-11-18 10:25:12

标签: java reflection singleton

我有各种单例模式的类。它们都是从抽象类扩展而来的。每个类都有一个getInstance()方法(具有完全相同的名称)。我想用类名(String)获取实例。例如

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");
  }
}

所有类与A类具有相同的结构。应该如何使用requiredFunction()?

我可以写“if .. else”,但我觉得应该有更优雅的方式。谢谢你提前帮忙......

2 个答案:

答案 0 :(得分:1)

您可以使用package.ClassName,反射和Class.forName(theName)中的完整班级名称。

例如使用String对象:

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
}

所以你的方法可能大致如下:

@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;
    }
}
OP的

编辑

(Class<?>[])null(Object[])nullnull个参数,被视为预期类型。

基本上:

  • getMethod的{​​{1}}方法使用Class表示方法的名称,以及String表示其参数类型的变量。我们调用的方法(Class<?>)不带参数,因此getInstance的参数为null,但我们希望将其转换为期望的参数。更多信息here
  • getMethod的{​​{1}}方法将invoke作为目标实例来调用方法(在我们的例子中,Method,因为它是类方法)和Object的varargs作为参数。但同样,您的null方法不带参数,因此我们使用Object并将其转换为getInstance数组。更多信息here

答案 1 :(得分:0)

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

如果为超类创建对象,则无法从子类中获取方法

 AbsCls[] array = new A[5]; //this create object for A

如果要调用超类方法用户super关键字

,则可以访问这两个类
    array[0]=neededFunction("A"); //// calling method from A
    array[1]=super.neededFunction("B");//// calling method from AbsCls