Warum sollte eine statische verschachtelte Schnittstelle in Java verwendet werden?

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

  •  09-06-2019
  •  | 
  •  

Frage

Ich habe gefunden, nur eine statische verschachtelte Schnittstelle in unserer Code-Basis.

class Foo {
    public static interface Bar {
        /* snip */
    }
    /* snip */
}

Ich habe das noch nie gesehen. Der ursprüngliche Entwickler ist außer Reichweite. Deshalb muss ich fragen SO:

Was ist die Semantik hinter einer statischen Schnittstelle? Was würde sich ändern, wenn ich die static entfernen? Warum sollte das jemand tun?

War es hilfreich?

Lösung

Die statische Schlüsselwort in dem obigen Beispiel ist redundant (eine verschachtelte Schnittstelle ist automatisch „statisch“) und kann ohne Auswirkung auf die Semantik entfernt werden; Ich würde empfehlen, es entfernt werden. Das gleiche gilt für „public“ auf Interface-Methoden und „public final“ auf Interface Felder -. Die Modifikatoren redundant sind und nur Unordnung auf den Quellcode hinzufügen

So oder so wird der Entwickler einfach erklärt eine Schnittstelle namens Foo.Bar. Es gibt keine weitere Verbindung mit der umgebenden Klasse, mit der Ausnahme, dass Code, die Foo Lage sein wird, nicht nicht zugreifen kann Foo.Bar entweder zuzugreifen. (Von Quellcode - Bytecode oder Reflexion kann Foo.Bar zugreifen, auch wenn Foo ist Paket-privat)

Es ist akzeptabel, Stil einer verschachtelte Schnittstelle auf diese Weise zu erstellen, wenn Sie es erwarten, nur von der äußeren Klasse verwendet werden, so dass Sie nicht einen neuen Top-Level-Namen erstellen. Zum Beispiel:

public class Foo {
    public interface Bar {
        void callback();
    }
    public static void registerCallback(Bar bar) {...}
}
// ...elsewhere...
Foo.registerCallback(new Foo.Bar() {
    public void callback() {...}
});

Andere Tipps

Die Frage beantwortet wurde, aber ein guter Grund, eine verschachtelte Schnittstelle zu verwenden ist, wenn ihre Funktion direkt auf die Klasse verwendet wird, ist es in. Ein gutes Beispiel hierfür ein Listener ist. Wenn Sie eine Klasse Foo haben und Sie andere Klassen wollten für Veranstaltungen auf sie hören zu können, können Sie eine Schnittstelle mit dem Namen FooListener erklären, die in Ordnung ist, aber es sei wahrscheinlich mehr klar sein, eine verschachtelte Schnittstelle zu erklären und hat die anderen Klassen implementieren Foo.Listener (eine verschachtelte Klasse Foo.Event ist nicht schlecht zusammen mit diesem).

Das Mitglied Schnittstellen ist implizit statisch. Der statische Modifier in Ihrem Beispiel kann ohne Änderung der Semantik des Codes entfernt werden. Siehe auch die Java Language Specification 8.5.1. Statische Member Erklärungen

Eine innere Schnittstelle besitzt statisch sein, um die zugegriffen werden soll. Die Schnittstelle ist nicht mit Instanzen der Klasse zugeordnet ist, sondern mit der Klasse selbst, so wäre es mit Foo.Bar zugegriffen werden, etwa so:

public class Baz implements Foo.Bar {
   ...
}

In den meisten Möglichkeiten, dies unterscheidet sich nicht von einer statischen inneren Klasse.

Jesse Antwort ist in der Nähe, aber ich glaube, dass es ein besserer Code zu zeigen, warum eine innere Schnittstelle nützlich sein kann. Betrachten Sie den Code unten, bevor Sie weiterlesen. Können Sie die innere Schnittstelle nützlich ist, warum? Die Antwort ist, dass die Klasse DoSomethingAlready mit instanziiert werden jeder Klasse, die A und C implementiert; nicht nur die konkrete Klasse Zoo. Natürlich kann dies auch erreicht werden, wenn AC nicht innere, aber vorstellen, längere Namen verketten (nicht nur A und C) und diese für andere Kombinationen zu tun (zum Beispiel A und B, C und B, etc.) und Sie leicht sehen, wie die Dinge außer Kontrolle geraten. Ganz zu schweigen davon, dass die Sourcen auf Ihrem Überprüfung Menschen werden durch Schnittstellen überwältigt werden, die nur sinnvoll sind, in einem class.So zusammenzufassen, eine innere Schnittstelle ermöglicht den Aufbau von benutzerdefinierten Typen und verbessert ihre Kapselung .

class ConcreteA implements A {
 :
}

class ConcreteB implements B {
 :
}

class ConcreteC implements C {
 :
}

class Zoo implements A, C {
 :
}

class DoSomethingAlready {
  interface AC extends A, C { }

  private final AC ac;

  DoSomethingAlready(AC ac) {
    this.ac = ac;
  }
}

Um Ihre Frage zu beantworten, sehr direkt, Blick auf Map.Entry.

Map.Entry

Auch dies kann nützlich sein,

Static Nested Inerfaces Blog Eintrag

Normalerweise sehe ich statische innere Klassen. Statische innere Klassen können die Klassen enthält, nicht Referenz wherease nicht-statische Klassen können. Es sei denn, Sie in einige Paket-Kollisionen laufen (es gibt bereits eine Schnittstelle Bar im selben Paket wie Foo genannt) Ich denke, ich es seine eigene Datei machen würde. Es könnte auch eine Design-Entscheidung, die logische Verbindung zwischen Foo und Bar zu erzwingen. Vielleicht ist der Autor beabsichtigt Bar nur mit Foo verwendet werden (obwohl eine statische innere Schnittstelle dies nicht erzwingen wird, nur eine logische Verbindung)

Wenn Sie Klasse Foo in Schnittstelle Foo ändern werden das „public“ Schlüsselwort in dem obigen Beispiel wird dabei auch überflüssig, da

  

Schnittstelle innerhalb einer anderen Schnittstelle definiert wird implizit öffentlich   statisch.

Im Jahr 1998 Philip Wadler einen Unterschied zwischen statischen Schnittstellen und nicht-statischen Schnittstellen vorgeschlagen.

  

So weit ich, der einzige Unterschied in der Herstellung einer sehen kann   Schnittstelle nicht statisch ist, dass es jetzt können, umfassen nicht-statische Innen   Klassen; so dass die Änderung machen würde nicht ungültig alle vorhandenen Java   Programme.

Zum Beispiel schlug er eine Lösung für den Expression Problem , die die Diskrepanz zwischen Ausdruck wie „wie viel können Sie Ihre Sprache ausdrücken“ auf der einen Seite und Ausdruck als „die Begriffe, die Sie in Ihrer Sprache zu repräsentieren versuchen,“ auf der anderen Seite.

Ein Beispiel für den Unterschied zwischen statischen und nicht-statischen nested-Schnittstellen kann in sein Beispielcode :

// This code does NOT compile
class LangF<This extends LangF<This>> {
    interface Visitor<R> {
        public R forNum(int n);
    }

    interface Exp {
        // since Exp is non-static, it can refer to the type bound to This
        public <R> R visit(This.Visitor<R> v);
    }
}

Sein Vorschlag machte es nie in Java 1.5.0. Daher sind alle andere Antworten richtig: Es gibt keinen Unterschied zu dem statischen und nicht-statischen verschachtelten Schnittstellen

.

In Java, die statische Schnittstelle / Klasse ermöglicht die Schnittstelle / Klasse wie eine Top-Level-Klasse verwendet werden, das heißt, es kann von anderen Klassen deklariert werden. So können Sie tun:

class Bob
{
  void FuncA ()
  {
    Foo.Bar foobar;
  }
}

Ohne die statische, würde die oben nicht kompilieren. Der Vorteil hierbei ist, dass Sie keine neue Quelldatei müssen Sie nur die Schnittstelle zu erklären. Es ist auch visuell verbindet die Schnittstelle Bar zur Klasse Foo, da Sie Foo.Bar schreiben müssen und bedeutet, dass die Foo-Klasse tut etwas mit Instanzen von Foo.Bar.

Eine Beschreibung der Klassentypen in Java .

Statisch bedeutet, dass jede Klasse ein Teil des Pakets (Projekt) es ohne Verwendung eines Zeigers acces kann. Dies kann je nach Situation sehr nützlich oder Behinderung sein.

Das perfekte Beispiel für die usefullnes von „statischen“ Methoden ist die Mathematik. Alle Methoden in Mathe sind statisch. Das heißt, Sie müssen nicht aus dem Weg zu gehen, eine neue Instanz machen, erklären Variablen und speichern sie in noch mehr Variablen, können Sie einfach Ihre Daten eingeben und ein Ergebnis bekommen.

Static ist nicht immer so nützlich. Wenn Sie Fall-Vergleich zum Beispiel tun, können Sie Daten auf verschiedene Weise zu speichern. Sie können nicht mehr als drei statische Methoden mit identischen Signaturen erstellen. Sie müssen 3 verschiedene Instanzen, nicht statisch, und dann können Sie und vergleichen, caus wenn sie statisch ist, werden die Daten nicht mit der Eingabe ändern zusammen.

Statische Methoden sind gut für einmalige Erträge und schnelle Berechnungen oder einfach erhaltenen Daten.

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