Java:实例化抽象类的特定子类的方法

3
如何根据在运行时生成的classNameString创建一个特定子类的对象呢?假设有一个抽象类A。
public abstract class A {
    abstract protected void method();               
    A getNewInstance() throws InstantiationException, IllegalAccessException{
        return this.getClass().newInstance();
    }
}

让我们假设有N个子类,例如A1、A2、...、AN。 需要编写以下方法,该方法将根据classNameString返回一个子类对象。
A getSubClassObject(String classNameString)

我有以下两个丑陋的实现方式: 第一个:

A getSubClassObject(String classNameString){
    A obj = null;
    if(classNameString.equals("A1")){
        obj = new A1();
    }else if(classNameString.equals("A2")){
        obj = new A2();         
    }
    ...
    }else if(classNameString.equals("AN")){
        obj = new AN();         
    }
    return obj;
}

第二点:

A getSubClassObject(String classNameString){
    A obj = null;
    try {
       obj = this.subClassObjectsHashMap().get(classNameString).getNewInstance();
    } catch (InstantiationException e) {
       e.printStackTrace();
    } catch (IllegalAccessException e) {
       e.printStackTrace();
    }
    return obj;
}
private HashMap<String, A> subClassObjectsHashMap(){
    HashMap<String, A> subClassObjectsHashMap = new HashMap<String,A>();
    subClassObjectsHashMap.put("A1", new A1());
    subClassObjectsHashMap.put("A2", new A2());
    ....
    subClassObjectsHashMap.put("AN", new AN());
    return subClassObjectsHashMap;
}

有没有更好的方法来解决这个问题?

构造类名并按名称加载该类。 - bmargulies
3个回答

4

做类似以下这样的事情怎么样

return (A)Class.forName(runtimeClassName).newInstance();

如何进行适当的错误处理?


2

是的,如果所有构造函数都接收相同的参数(在您的示例中,没有参数),您可以执行以下操作:

Class clazz = Class.forName("fully.qualified.class.nane");
A a = (A) clazz.newInstace();

两种方法都可以抛出各种异常,因此您需要添加一些catch块。


如果所有子类都有相同的参数怎么办?例如,基类构造函数是A(String str){},而子类构造函数如下:A1(String str, String str2) {super(str);} - porsh
然后你需要调用类似 Constructor c = Clazz.getConstructor( new Object[] {String.class} ); 的东西,它返回一个以 String 为参数的构造函数。然后 A a = c.newInstance( new Object["your_string"] )。了解一下 Java 反射,它是 Java 中允许在运行时打开类并做一些有趣的事情的特性(比如调用私有方法 :p)。 - Augusto
谢谢指点!Java反射确实很酷,正是我想要的 :) - porsh

0

请在Java API中查看java.lang.Class,方法为forName(String)和newInstance()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接