Java 使用反射从抽象基类访问构造函数
我正在玩Java的反射。我有一个带有构造函数的抽象类Java 使用反射从抽象基类访问构造函数,java,reflection,constructor,Java,Reflection,Constructor,我正在玩Java的反射。我有一个带有构造函数的抽象类Base abstract class Base { public Base( String foo ) { // do some magic } } 我还有一些扩展Base的类。它们没有多少逻辑性。我想用Base的构造函数实例化它们,而不必在这些派生类中编写一些代理构造函数。当然,我想用反射实例化这些派生类。说: Class cls = SomeDerivedClass.class; Constructor
Base
abstract class Base {
public Base( String foo ) {
// do some magic
}
}
我还有一些扩展Base
的类。它们没有多少逻辑性。我想用Base
的构造函数实例化它们,而不必在这些派生类中编写一些代理构造函数。当然,我想用反射实例化这些派生类。说:
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
有什么想法吗?我如何用基类的构造函数实例化派生类?或者我必须声明那些哑代理构造函数吗?问题是基类构造函数是非默认的(有一个参数)。因此,它不能被生成的默认子类构造函数隐式调用。(事实上,你应该得到一个编译警告/错误。)我担心你需要添加显式子类构造函数。我担心你的子类甚至不会编译,除非你有一个显式构造函数调用其中一个super()构造函数。一个类不会从它的父类继承构造函数。一个类没有它的父构造函数(尽管它可以调用它们),所以你必须调用这个类拥有的构造函数,而不是一个超类拥有的构造函数
默认构造函数似乎只执行此操作,因为它在默认情况下调用父级的默认构造函数。如果父级没有默认构造函数,则其直接子级也不能。如果不指定将使其成为“非抽象”的所有详细信息,则无法构造抽象类 这意味着在示例中:
public abstract class Parent {
String name;
public Parent(String name) {
this.name = name;
}
abstract public String getName();
}
通过反射进行操作的构造函数不会返回仅父类。但是,您可以通过在构造时指定抽象细节来返回“匿名”类,如下所示:
Parent parent = new Parent() {
public String getName() { return "Bob"; }
};
记住,子分类也会调用父构造函数,即使您没有显式地将代码放入。子类的编写方式如下:
public class Child extends Parent {
public Child(String name) {
}
}
将在父类中查找无参数构造函数。如果它找到一个,那么它将被编译成与
public class Child extends Parent {
public Child(String name) {
super();
}
}
如果在父类
中找不到无参数构造函数,它将无法编译,直到您使用super(名称)显式指定父类构造代码>构造函数调用
要记住的另一件事是,所有类都是对象的子类,因此如果不提供扩展SomeClass
,如下所示:
public class JustMe {
}
编译器会在编译时将您的代码“更正”为:
public class JustMe extends Object {
public JustMe() {
super();
}
}
对象类中有一堆本机(非Java)代码,用于向JVM注册,以确保在对象的生命周期中遵循正确的垃圾收集、内存管理、类型强制等
例如,你无法绕过它,JVM将阻止你构造和抽象类,除非它的所有方法都可以通过匿名类或子类来解析。在实例化这些类之前,你确定所有的东西都在编译吗?是的,它编译得很好。这是一个简化的示例,它缺少那些catch子句,但基本上这段代码编译得很好。啊,而且Base
还有一个额外的空默认构造函数(javac坚持这样做)。我没有收到任何警告。可能是因为Base
和派生类驻留在不同的包中,位于不同的Eclipse项目中Base(String)
不会在任何子类中被调用。但是我必须为Base
定义一个空的默认构造函数,这是一个关键的区别。这意味着子类将编译ans实例化,但只调用空的父构造函数。除非子类在其构造函数中显式调用它,否则无法访问其他构造函数。子类化只隐式调用无参数父构造函数(如果存在)。它肯定不会自己传递参数。此外,如果抽象类的构造函数需要一个参数,那么您也应该在创建匿名类时指定它,因此anon示例应该是:new Parent(“foo”){…}@biziclop感谢您的出色观察,为了子孙后代的缘故进行了后期更正