1

メソッド参照を検索して呼び出すGroovyクラスがあります。呼び出されるメソッドはプライベートメソッドです。実際のクラスが子クラスのインスタンスである場合、実際にそれを呼び出すのは親のパブリックメソッドであるにもかかわらず、プライベートメソッドが見つからないというエラーをスローします。

この場合、私は明らかにpMethod2()直接呼び出すことができ、それは機能しますが、これが書かれたとおりに機能しない理由と、それを修正して機能する方法があるかどうかを理解しようとしています。

class Parent {

  def pMethod1() {
    def m = this.&pMethod2
    m() // this call fails if the calling class is of type Child
  }


  private def pMethod2() {}

  public static void main(String[] args) {
    new Child().pMethod1();
  }
}

class Child extends Parent {}
4

1 に答える 1

5

特にC/C ++に慣れている場合は、少し混乱します。Groovyで「。&」演算子を使用すると得られるのはアドレスではなく、MethodClosureのインスタンスです。

MethodClosureオブジェクトには、呼び出すメソッドを解決するときに使用される所有者オブジェクトと委任オブジェクトが含まれています。この例では、所有者とデリゲートオブジェクトは、Childのインスタンスである「this」になります。呼び出すメソッドは、単純に文字列として保存されます。

だから、割り当て

m = this.&pMethod2

速記の書き方です

m = new MethodClosure(this, "pMethod2")

m()クロージャを呼び出すと、所有者オブジェクトとデリゲートオブジェクトでそれぞれ「pMethod2」という名前のメソッドを探して、(実行時に)メソッドを解決しようとします。所有者とデリゲートはChildのインスタンスであるため、Parentにあるプライベートメソッドは見つかりません。

サンプルを機能させるには、クロージャーの所有者や委任者にメソッドが表示されることを確認する必要があります。

これは、いくつかの方法で実行できます。たとえば、pMethod2のアクセス修飾子をprotectedに変更したり、Parentのインスタンスを使用してクロージャーを作成したりします。このようなもの:

m = new Parent().&pMethod2

pMethod2が実際に表示されているメソッドでMethodClosureインスタンスを作成したことは関係ありません。また、クロージャが表示されているメソッドでクロージャを呼び出すことも関係ありません。メソッドは、メソッドを解決するときに使用されているMethodClosureの所有者または委任者には表示されません。

于 2013-02-09T20:39:38.190 に答える