使用reflection从抽象基类访问构造函数
我正在玩Java的Reflection。 我有一个带有构造函数的抽象类Base
。
abstract class Base { public Base( String foo ) { // do some magic } }
我还有一些扩展Base
类。 它们没有太多逻辑。 我想用Base
的构造函数实例化它们,而不必在这些派生类中编写一些代理构造函数。 当然,我想用Reflection实例化那些派生类。 说:
Class cls = SomeDerivedClass.class; Constructor constr; constr = cls.getConstructor( new Class[] { String.class } ); // will return null Class clsBase = Base.class; constr = clsBase.getConstructor( new Class[] { String.class } ); // ok Base obj = (Base) constr.newInstance( new Object[] { "foo" } ); // will throw InstantiationException because it belongs to an abstract class
任何想法,我如何使用Base的构造函数实例化派生类? 或者我必须声明那些愚蠢的代理构造函数?
类不从父级inheritance构造函数。 类没有父类构造函数(虽然它可以调用它们)所以你必须调用类所具有的构造函数,而不是超类所具有的构造函数。
默认构造函数似乎只是这样做,因为它默认调用父项的默认构造函数。 如果父级没有默认构造函数,则它的直接子级也不能。
我担心你的子类甚至不会编译,直到你有一个显式构造函数调用其中一个super()构造函数。
如果不指定将使其成为“非抽象”的所有细节,则无法构造抽象类。
这意味着在示例中:
public abstract class Parent { String name; public Parent(String name) { this.name = name; } abstract public String getName(); }
没有任何构造函数通过reflection操作将返回一个Parent-only类。 但是,您可以通过在构造时指定抽象详细信息来返回“匿名”类,如下所示:
Parent parent = new Parent() { public String getName() { return "Bob"; } };
请记住,即使您没有明确地放置代码,子类也会调用父构造函数。 一个写成如下的子类:
public class Child extends Parent { public Child(String name) { } }
将在Parent
类中查找no arg构造函数。 如果找到一个,那么它将被编译成相当于的代码
public class Child extends Parent { public Child(String name) { super(); } }
如果在Parent
类中没有找到无参数构造函数,则在使用super(name);
显式指定父类构造之前,它将无法编译super(name);
构造函数调用。
另外要记住的是,所有类都是Object
子类,所以如果你没有像这样提供一个extends SomeClass
:
public class JustMe { }
编译器会在编译时将您的代码“纠正”到:
public class JustMe extends Object { public JustMe() { super(); } }
Object类中有一堆本机(非Java)代码,用于向JVM注册,确保在Object的生命周期内遵循正确的垃圾收集,内存管理,类型实施等。
即。 你不能绕过它,JVM将阻止你构建和抽象类,除非所有的方法都可以通过匿名类或子类来解决。
问题是你的基类构造函数是非默认的(有一个参数)。 因此,生成的默认子类构造函数无法隐式调用它。 (实际上你应该得到关于此的编译警告/错误。)我担心你需要添加显式的子类构造函数。