簡體   English   中英

使用反射從抽象基類訪問構造函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM