Warum kann nicht nenne ich eine Methode außerhalb von einer anonymen Klasse mit dem gleichen Namen

StackOverflow https://stackoverflow.com/questions/252267

Frage

Der Code am Ende erzeugt einen Compiler-Fehler:

NotApplicable.java:7: run() in  cannot be applied to (int)
                run(42);
                ^
1 error

Die Frage ist, warum? Warum denkt Javac Ich betreibe ich () aufrufen, und nicht finden Lauf (int bar)? Es richtig foo (int bar) genannt. Warum muss ich NotApplicable.this.run (42) ;? Ist es ein Fehler?

public class NotApplicable {

    public NotApplicable() {
        new Runnable() {
            public void run() {
                foo(42);
                run(42);
                // uncomment below to fix
                //NotApplicable.this.run(42);
            }
        };
    }

    private void run(int bar) {
    }

    public void foo(int bar) {
    }
}
War es hilfreich?

Lösung

Die Erklärung für das Verhalten Ihrer Codebeispiel ist, dass this definiert ist, um die Klasse zu sein, die Sie gerade sind „die meisten“ innerhalb von. In diesem Fall sind Sie „die meisten“ innerhalb der anonyme innere Klasse, die runnable Unterklassen, und es gibt keine Methode, die run(int) entspricht. Erweitern Sie Ihre Suche Sie festlegen, welche this Sie unter Angabe NotApplicable.this.run(42) verwenden möchten.

Die JVM wird bewerten, wie folgt:

this -> zur Zeit Instanz Runnable mit Methode run() Ausführung

NotApplicable.this -> zur Zeit Instanz NotApplicable mit Methode run(int) Ausführung

Der Compiler wird die Verschachtelung Baum für das erste Verfahren sehen, dass der Name des Verfahrens entspricht. -Danke für diese Klarstellung DJClayworth

Die anonyme innere Klasse ist keine Unterklasse der äußeren Klasse. Wegen dieser Beziehung sind sowohl die innere Klasse und die äußere Klasse sollte ein Verfahren zu haben, mit genau die gleiche Signatur und der innerste Codeblock der Lage sein, es sollte in der Lage zu erkennen, welche Methode ausführen möchte.

public class Outer{

    public Outer() {
        new Runnable() {
            public void printit() {
                System.out.println( "Anonymous Inner" );
            }
            public void run() {
                printit(); // prints "Anonymous Inner"
                this.printit(); //prints "Anonymous Inner"

                // would not be possible to execute next line without this behavior
                Outer.this.printit(); //prints "Outer" 
            }
        };
    }

    public void printit() {
        System.out.println( "Outer" );
    }
}

Andere Tipps

Soweit ich die Regeln für die Auswahl eines Methode lade zwischen verschachtelten Klassen auszuführen, sind ungefähr die gleiche wie die Regeln für ein Verfahren in einer Vererbungsbaum auswählen. Das bedeutet, dass das, was wir hier bekommen ist nicht zu überlasten, es versteckt. Der Unterschied zwischen ihnen ist von entscheidender Bedeutung für das Verständnis Methoden bei der Vererbung.

Wenn Ihr Runnable wurde als eine Unterklasse deklariert, dann ist die Methode run () würde den Lauf (int) -Methode in den Eltern verstecken. Jeder Aufruf laufen (...) versuchen würde, den man auf Runnable auszuführen, würde aber fehlschlagen, wenn es nicht Signaturen entsprechen könnte. Da foo in dem Kind erklärt wird dann nicht die auf der Mutter genannt wird.

Das gleiche Prinzip geschieht hier. Nachschlagen Verweise auf „Methode versteckt“ und es sollte klar sein.

Das ist, weil run erneut erklärt wird, wenn Sie den new Runnable() {} Umfang ein. Alle bisherigen Bindungen zum laufen nicht mehr zugegriffen werden. Es ist, als ob Sie dies taten:

import java.util.*;

public class tmp
{
  private int x = 20;
  public static class Inner
  {
      private List x = new ArrayList();
      public void func()
      {
          System.out.println(x + 10);
      }
  }

  public static void main(String[] args)
  {
    (new Inner()).func();
  }
}

Der Compiler für nicht etwas sucht, die die Art der x passt den ganzen Weg der Umfang Stack, es wird nur anhalten, wenn es die ersten Hinweise findet und sieht, dass die Arten nicht kompatibel sind.

Hinweis: Es ist nicht, als ob es konnte nicht tut dies ... es ist nur, dass Sie Ihre eigene geistige Gesundheit zu bewahren, ist es entschieden worden ist, dass es nicht .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top