Java 使用类名从不同类调用方法

Java 使用类名从不同类调用方法,java,reflection,singleton,Java,Reflection,Singleton,我有很多单件模式的课程。它们都是从抽象类扩展而来的。每个类都有一个getInstance()方法(具有完全相同的名称)。我想用类名(字符串)获取实例。比如说 public abstract class AbsCls { } 所有类的结构都与类A相同。neededFunction()应该是什么样的 我可以写“如果……否则”,但我觉得应该有一种更优雅的方式。谢谢你事先的帮助 AbsCls[] array = new AbsCls[5]; // this create object for Ab

我有很多单件模式的课程。它们都是从抽象类扩展而来的。每个类都有一个getInstance()方法(具有完全相同的名称)。我想用类名(字符串)获取实例。比如说

public abstract class AbsCls {
}


所有类的结构都与类A相同。neededFunction()应该是什么样的

我可以写“如果……否则”,但我觉得应该有一种更优雅的方式。谢谢你事先的帮助

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
如果要调用超级类方法user
super
关键字,则可以访问这两个类

    array[0]=neededFunction("A"); //// calling method from A
    array[1]=super.neededFunction("B");//// calling method from AbsCls
若为超类创建对象,则无法从子类获取方法

 AbsCls[] array = new A[5]; //this create object for A
如果要调用超级类方法user
super
关键字,则可以访问这两个类

    array[0]=neededFunction("A"); //// calling method from A
    array[1]=super.neededFunction("B");//// calling method from AbsCls

您可以在
package.ClassName
、reflection和
class.forName(theName)
中使用完整的类名

例如,使用
字符串
对象:

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;
    }
}
@SuppressWarnings(“未选中”)
公共静态getInstance(字符串clazz){
//TODO检查clazz null
试一试{
return(T)Class.forName(clazz).getMethod(“getInstance”,“Class[])null.invoke(null,(Object[])null);
}
捕获(ClassNotFoundException cnfe){
//待办事项处理
返回null;
}
捕获(NoSuchMethodException nsme){
//待办事项处理
返回null;
}
捕获(调用targetException ite){
//待办事项处理
返回null;
}
捕获(IllegalacessException iae){
//待办事项处理
返回null;
}
}
为OP编辑

(Class[])null
(Object[])null
是作为预期类型强制转换的
null
参数

基本上:

  • Class
    getMethod
    方法采用表示方法名称的
    String
    和表示其参数类型的
    Class
    变量。我们调用的方法(
    getInstance
    )不带参数,因此
    getMethod
    的参数为null,但我们希望将其转换为预期参数。更多信息
  • method
    invoke
    方法将
    Object
    作为调用方法的目标实例(在我们的例子中,
    null
    ,因为它是类方法)和
    Object
    的varargs作为参数。但是同样,您的
    getInstance
    方法不接受任何参数,因此我们使用
    null
    并将其转换为
    对象的数组。更多信息

您可以使用完整的类名,如
包.ClassName
、反射和
类.forName(theName)

例如,使用
字符串
对象:

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;
    }
}
@SuppressWarnings(“未选中”)
公共静态getInstance(字符串clazz){
//TODO检查clazz null
试一试{
return(T)Class.forName(clazz).getMethod(“getInstance”,“Class[])null.invoke(null,(Object[])null);
}
捕获(ClassNotFoundException cnfe){
//待办事项处理
返回null;
}
捕获(NoSuchMethodException nsme){
//待办事项处理
返回null;
}
捕获(调用targetException ite){
//待办事项处理
返回null;
}
捕获(IllegalacessException iae){
//待办事项处理
返回null;
}
}
为OP编辑

(Class[])null
(Object[])null
是作为预期类型强制转换的
null
参数

基本上:

  • Class
    getMethod
    方法采用表示方法名称的
    String
    和表示其参数类型的
    Class
    变量。我们调用的方法(
    getInstance
    )不带参数,因此
    getMethod
    的参数为null,但我们希望将其转换为预期参数。更多信息
  • method
    invoke
    方法将
    Object
    作为调用方法的目标实例(在我们的例子中,
    null
    ,因为它是类方法)和
    Object
    的varargs作为参数。但是同样,您的
    getInstance
    方法不接受任何参数,因此我们使用
    null
    并将其转换为
    对象的数组。更多信息

我建议您阅读并实施访问者设计模式我建议您阅读并实施访问者设计模式,但由于单例模式,A、B、C的构造函数。。。课程是私人的。所以newInstance()方法不起作用。我使用.getInstance()创建一个对象……它成功了。谢谢。但是如果你有时间可以解释“(Class[])null”和“(Object[])null”,我们将不胜感激……。@s.alem不客气:)我将在我的回答中对这些参数进行评论。但是由于单例模式,A、B、C的构造函数。。。课程是私人的。所以newInstance()方法不起作用。我使用.getInstance()创建一个对象……它成功了。谢谢。但如果您有时间解释“(Class[])null”和“(Object[])null,我们将不胜感激……。@s.alem不客气:)我将在回答中对这些参数进行评论。