![](/img/trans.png)
[英]Override super class constructor with base class constructor using Reflection
[英]Accessing constructor from abstract base class with 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的構造函數實例化派生類? 或者我必須聲明那些愚蠢的代理構造函數?
類不從父級繼承構造函數。 類沒有父類構造函數(雖然它可以調用它們)所以你必須調用類所具有的構造函數,而不是超類所具有的構造函數。
默認構造函數似乎只是這樣做,因為它默認調用父項的默認構造函數。 如果父級沒有默認構造函數,則它的直接子級也不能。
我擔心你的子類甚至不會編譯,直到你有一個顯式構造函數調用其中一個super()構造函數。
如果不指定將使其成為“非抽象”的所有細節,則無法構造抽象類。
這意味着在示例中:
public abstract class Parent {
String name;
public Parent(String name) {
this.name = name;
}
abstract public String getName();
}
沒有任何構造函數通過反射操作將返回一個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將阻止你構建和抽象類,除非它的所有方法都可以通過匿名類或子類來解決。
問題是你的基類構造函數是非默認的(有一個參數)。 因此,生成的默認子類構造函數無法隱式調用它。 (實際上你應該得到關於此的編譯警告/錯誤。)我擔心你需要添加顯式的子類構造函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.