【问题标题】:Create an instance within Abstract Class using Reflection使用反射在抽象类中创建一个实例
【发布时间】:2012-11-19 09:32:18
【问题描述】:

是否可以使用反射在抽象祖先类中创建派生类的实例 让我们说:

abstract class Base {

public Base createInstance(){
  //using reflection
    Class<?> c = this.getClass();
    Constructor<?> ctor = c.getConstructor();
    return ((Base) ctor.newInstance());
}

}//end Base

class Derived extends Base {

 main(){

new Derived().createInstance()

 }

}

【问题讨论】:

  • 你试过了吗?似乎它会工作。
  • 你尝试的时候发生了什么?您可以这样做,但这是一个相当可疑的设计选择。
  • @PeterLawrey 这可能是一种复制方法。
  • 请注意,您正在浪费代码行:public Base createInstance() { return (Base) getClass().newInstance(); } 就是您所需要的(模块例外)。
  • 嗯。该代码甚至一开始就无法编译。无论如何,当你尝试它时发生了什么?>

标签: java reflection abstract-class


【解决方案1】:

你可以这样做

public class Derived extends Base {
    public static void main(String ... args) {
        System.out.println(new Derived().createInstance());
    }
}

abstract class Base {
    public Base createInstance() {
        //using reflection
        try {
            return getClass().asSubclass(Base.class).newInstance();
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

打印

Derived@55fe910c

更常见的模式是使用 Cloneable

public class Derived extends Base {
    public static void main(String ... args) throws CloneNotSupportedException {
        System.out.println(new Derived().clone());
    }
}

abstract class Base implements Cloneable {
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

打印

Derived@8071a97

但是,应避免使用任何一种。通常有另一种方法来做你需要的事情,这样 base 就不会隐式依赖于derived。

【讨论】:

    【解决方案2】:

    证明它有效很容易:

    abstract class Base {
      public Base createInstance() throws Exception {
        return getClass().newInstance();
      }
    }
    
    public class Derived extends Base {
      public static void main(String[] args) throws Exception {
        System.out.println(new Derived().createInstance().getClass());
      }
    }
    

    打印

    class test.Derived
    

    您应该问自己两次为什么需要它,以及它是否真的是解决问题的好方法。如果您需要克隆,请考虑clone 机制,它的作用基本相同。

    【讨论】:

    • 我正在尝试编写一个 API(覆盖 Base 抽象类)。我需要这个 Base 类的 deepCopy 方法。
    • 深拷贝一般是无法解决的,反正。您需要为每个类仔细考虑自定义代码。这就是为什么通过泛化实例创建代码获得很少的原因。
    【解决方案3】:

    您可以使用Class.forName()Class.newInstance() 创建任何类。但是没有办法轻松地识别一个类的子类。请参阅 this JavaWorld tip 了解执行此操作的技术。

    不过,我认为,真正的问题是您最终要达到的目标是什么,以及使用传统技术是否可以更轻松地完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      相关资源
      最近更新 更多