Frage

Gibt es eine Möglichkeit andere als Reflexion über die Mitglieder einer anonymen inneren Klasse zugreifen?

War es hilfreich?

Lösung

Anonyme innere Klassen haben einen Typen, aber keinen Namen.

Sie können die Felder nicht durch die Namen übergeordneten Typen definiert zugreifen. Jedoch einmal zu einem benannten Typ Variablen zugewiesen, die Schnittstelle verloren.

Natürlich können Sie die Felder aus der inneren Klasse zugreifen selbst. Eine Möglichkeit, Code hinzuzufügen, ist durch eine Instanz initialiser:

final AtomicInteger y = new AtomicInteger();
new Runnable() {
    int x;
    {
        x = 5;
        doRun(this);
        y.set(x);
    }
    public void run() {
        ... blah ...
    }
};

Der Wert des anonymen innere Klasse Ausdruck zurückgegeben hat den anonymen Typen, so dass Sie eine Chance haben, es zu benutzen, außerhalb der Klasse selbst:

final int y = new Runnable() {
    int x;
    {
        x = 5;
        doRun(this);
    }
    public void run() {
        ... blah ...
    }
}.x;

Sie können es auch durch eine Methode übergeben erklärte ähnlich wie:

<T extends Runnable> T doRun(T runnable);

Andere Tipps

Sie können lokale Klassen statt anonyme Klasse verwenden. Schauen Sie:

public class Test {
    public static void main(String... args) {
        class MyInner {
            private int value = 10;
        }

        MyInner inner = new MyInner();
        System.out.println(inner.value);
    }
}

Sie können anhand von MyInner haben allerdings nur in der Methode Körper geben. So außerhalb der Methode, die Sie nicht in der Lage sein, seine Felder / Methoden zu verwenden, die nicht in der Super-Klasse deklariert ist (java.lang.Object in diesem Fall) oder Schnittstelle.


public class AccessAnonymous {
    private Runnable runnable; // to have instance of the class

    public static void main(String[] args) throws Exception {
        AccessAnonymous a = new AccessAnonymous();
        a.a(); // init field

        Class clazz = a.runnable.getClass();
        Field field = clazz.getDeclaredField("i");
        field.setAccessible(true);

        int int1 = field.getInt(a.runnable);
        System.out.println("int1=" + int1);
    }

    public void a() {
        runnable = new Runnable() {
            private int i = 1;

            public void run() {
                i = 90;
            }

        };
        runnable.run();// change value
    }
}

Im Fall von anonymen Klassen gibt es auch einen Kompromiss zwischen der von der Klasse verursachte Unordnung und der Bequemlichkeit es anonym ist. Komplizierte Klassen gehören selten so anonym, sondern als private innere benannt.

In den meisten anonymen Klassen, wir brauchen nur zu „füttern“ Wissen und kann es auf dem Bau tun. In wenigen anonymen Klassen (zum Beispiel Rückgabewert Fahrzeuge) kümmern wir uns auch um einen Rückgabewert.

Wie wir wissen, Datenelemente sollten nicht direkt zugegriffen werden, sondern mit einem Getter Setter. Dies, wenn Sie sich in einer Situation befinden, die Sie viele Getter und Setter hinzugefügt haben, sind Sie wahrscheinlich etwas falsch sowieso tun und sollte nicht eine anonyme Klasse werden.

Wenn es eine Schnittstelle oder erweitert eine bestehende Klasse implementiert, können Sie die Mitglieder in der Schnittstelle oder Basisklasse definiert zugreifen zu können.

Herr Fooz ist richtig, mit der Ausnahme, dass Schnittstellen nur konstante Elemente definieren kann. der beste Weg wäre, um Getter / Setter-Methoden zu Ihrer Schnittstelle hinzufügen und dann diejenigen, Ihren Wert zu erhalten verwenden. aber dann für jede anonyme Klasse würden Sie diese Methoden (eine Art Schmerz) definieren.

Wenn Sie lesbar, wartbar Code möchten, verwenden Sie keine anonymen Klassen. Wenn Sie die anonymen Klassen verwenden und wollen lesbar, wartbar Code, nicht anonyme Klassen verwenden, wenn Sie das Element in dieser inneren Klasse zugreifen müssen. Es gibt Möglichkeiten, dies zu tun, aber ich bitte Sie, keine dieser Hacks zu verwenden. Ablesbarkeit trumpft alle anderen Tugenden.

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