Was ist der Zweck des Standardschlüsselworts in Java?

Lesezeit: 9 Minuten

Benutzer-Avatar
Ravi

Eine Schnittstelle in Java ähnelt einer Klasse, aber der Hauptteil einer Schnittstelle kann enthalten nur abstrakte Methoden und final Felder (Konstanten).

Kürzlich sah ich eine Frage, die so aussieht

interface AnInterface {
    public default void myMethod() {
        System.out.println("D");
    }
}

Gemäß der Schnittstellendefinition nur abstrakte Methoden sind erlaubt. Warum kann ich den obigen Code kompilieren? Was ist der default Stichwort?

Auf der anderen Seite, als ich versuchte, den folgenden Code zu schreiben, hieß es modifier default not allowed here

default class MyClass{

}

Anstatt von

class MyClass {

}

Kann mir jemand den Zweck der default Stichwort? Ist es nur innerhalb einer Schnittstelle erlaubt? Wie unterscheidet es sich von default (kein Zugriffsmodifikator)?

  • Standardmethoden in Schnittstellen wurden in Java 8 hinzugefügt. Es ist kein Zugriffsmodifizierer, es ist eine Standardimplementierung.

    – Eran

    23. Juli 2015 um 4:56 Uhr


  • @Eran meinst du nicht, die Einführung der Standardmethode verstößt gegen die Schnittstellendefinition? :s

    – Ravi

    23. Juli 2015 um 4:59 Uhr

  • Es hat die Schnittstellendefinition geändert. Diese Definition ist mittlerweile veraltet.

    – Louis Wassermann

    23. Juli 2015 um 5:00 Uhr

  • Sie wurden eingeführt, um Lambdas zu unterstützen. Die Einzelheiten, warum sie erforderlich sind, finden Sie im Strohmann-Vorschlag für Project Lambda.

    – Sprinter

    23. Juli 2015 um 6:10 Uhr

Es ist eine neue Funktion in Java 8, die eine interface eine Implementierung bereitzustellen. Beschrieben in Java 8 JLS-13.5.6. Deklarationen von Schnittstellenmethoden was (teilweise) lautet

Hinzufügen eines default Methode oder Ändern einer Methode von abstract zu defaultunterbricht nicht die Kompatibilität mit bereits vorhandenen Binärdateien, kann aber eine IncompatibleClassChangeError wenn eine bereits vorhandene Binärdatei versucht, die Methode aufzurufen. Dieser Fehler tritt auf, wenn der qualifizierende Typ, Tist ein Untertyp von zwei Schnittstellen, I und Jwo beides I und J erklären a default Methode mit der gleichen Signatur und dem gleichen Ergebnis und keines von beiden I Noch J ist eine Unterschnittstelle des anderen.

Was ist neu in JDK 8 sagt (teilweise)

Standardmethoden ermöglichen das Hinzufügen neuer Funktionen zu den Schnittstellen von Bibliotheken und stellen die Binärkompatibilität mit Code sicher, der für ältere Versionen dieser Schnittstellen geschrieben wurde.

  • Es scheint, dass Schnittstelle und abstrakte Klasse jetzt fast gleich sind. 🙂

    – Ravi

    23. Juli 2015 um 5:09 Uhr

  • @jWeaver-Schnittstellen können immer noch keine Konstruktoren, Felder, privaten Methoden oder Implementierungen von equals/hashCode/toString haben.

    – Louis Wassermann

    23. Juli 2015 um 5:21 Uhr


  • @Louis Wasserman: In Java 9 können sie das haben private Methoden.

    – Holger

    23. Juli 2015 um 8:15 Uhr

  • @ Dan Speisekammer: private Methoden sind nicht wirklich Teil der Schnittstelle, können aber als Hilfsmethoden für die dienen default Implementierungen oder innerhalb konstanter Initialisierer. Beachten Sie, dass sie bereits in Java 8 vorhanden sind, da, wenn Sie Lambda-Ausdrücke innerhalb von Schnittstellen verwenden, synthetische private Methoden generiert werden. Mit Java 9 können Sie diese Funktion also auch für nicht-synthetische, nicht-Lambda-Anwendungen verwenden …

    – Holger

    23. Juli 2015 um 10:28 Uhr


  • @jWeaver Der Unterschied zwischen Schnittstellen und Klassen reduziert sich auf Zustand vs Verhalten. Schnittstellen können Verhalten tragen, aber nur Klassen können einen Zustand haben. (Bei Feldern, Konstruktoren und Methoden wie equals/hashCode geht es um den Zustand.)

    – Brian Götz

    23. Juli 2015 um 19:27 Uhr

Benutzer-Avatar
Sprinter

Standardmethoden wurden zu Java 8 hinzugefügt, hauptsächlich um Lambda-Ausdrücke zu unterstützen. Die Designer entschieden sich (meiner Meinung nach geschickt) für eine Lambdas-Syntax, um anonyme Implementierungen einer Schnittstelle zu erstellen. Da Lambdas jedoch nur eine einzige Methode implementieren können, wären sie auf Schnittstellen mit einer einzigen Methode beschränkt, was eine ziemlich strenge Einschränkung wäre. Stattdessen wurden Standardmethoden hinzugefügt, um die Verwendung komplexerer Schnittstellen zu ermöglichen.

Wenn Sie etwas Überzeugungsarbeit von der Behauptung brauchen default aufgrund von Lambdas eingeführt wurde, beachten Sie, dass die Strohmann Vorschlag of Project Lambda, von Mark Reinhold, im Jahr 2009, erwähnt „Erweiterungsmethoden“ als obligatorisches Feature, das hinzugefügt werden muss, um Lambdas zu unterstützen.

Hier ist ein Beispiel, das das Konzept demonstriert:

interface Operator {
    int operate(int n);
    default int inverse(int n) {
        return -operate(n);
    }
}

public int applyInverse(int n, Operator operator) {
    return operator.inverse(n);
}

applyInverse(3, n -> n * n + 7);

Sehr erfunden, merke ich, sollte aber veranschaulichen, wie default unterstützt Lambdas. Da inverse ist ein Standardwert, der bei Bedarf leicht von einer implementierenden Klasse überschrieben werden kann.

  • Das ist nicht wirklich richtig. Lambdas mögen die unmittelbare Ursache sein, aber sie waren wirklich nur der Tropfen, der das Fass zum Überlaufen gebracht hat. Die eigentliche Motivation war die Ermöglichung Schnittstellenentwicklung (ermöglichen, dass vorhandene Schnittstellen kompatibel weiterentwickelt werden, um neues Verhalten zu unterstützen); Lambdas mögen der Faktor gewesen sein, der diese Notwendigkeit in den Vordergrund gerückt hat, aber das Feature ist allgemeiner als das.

    – Brian Götz

    23. Juli 2015 um 16:30 Uhr

  • @BrianGoetz: IMHO hätten sowohl Java als auch .NET enorm davon profitiert, wenn von Anfang an Standardmethoden vorhanden gewesen wären. Wenn eine allgemeine Operation an einer beliebigen Implementierung einer Schnittstelle nur unter Verwendung von Schnittstellenmitgliedern ausgeführt werden könnte, aber einige Implementierungen wahrscheinlich eine effizientere Möglichkeit hätten, dies auszuführen, sollte die Schnittstelle Methoden für diese Operationen definieren und Standardimplementierungen für sie bereitstellen. Die Unfähigkeit, Standardimplementierungen anzugeben, hat den Druck erzeugt, dass Schnittstellen solche Methoden weglassen, und es ihnen unmöglich gemacht, sie später hinzuzufügen.

    – Superkatze

    23. Juli 2015 um 21:20 Uhr

  • @BrianGoetz Ich stimme zu, dass Standardmethoden über Lambdas hinaus einen erheblichen Wert haben. Aber ich wäre an jedem Hinweis interessiert, den Sie auf diesen breiteren Wert geben können, der die Entscheidung antreibt, sie aufzunehmen. Ich habe gelesen, dass Lambdas der Hauptgrund waren (weshalb ich in meiner Antwort das Wort “hauptsächlich” verwendet habe).

    – Sprinter

    23. Juli 2015 um 23:53 Uhr

  • Vielleicht hilft dieses Dokument weiter: cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html. Abschnitt 10 sagt eindeutig: “Der Zweck von Standardmethoden (früher als virtuelle Erweiterungsmethoden oder Defender-Methoden bezeichnet) besteht darin, Schnittstellen zu ermöglichen, nach ihrer ursprünglichen Veröffentlichung auf kompatible Weise entwickelt zu werden.” Lambda-freundliche Methoden werden dann als ein zitiert Illustration der Interface-Evolution.

    – Brian Götz

    24. Juli 2015 um 21:41 Uhr

  • @Kartik Du stellst die falsche Frage! Wir wählen die Syntax nicht basierend auf “was ist das absolute Minimum, das der Compiler benötigt, um das Programm korrekt zu analysieren”; Wir wählen es auf der Grundlage, “was die Absicht des Programmierers für die Leser unmittelbar erkennbar machen würde”. Wir entwerfen zuerst für Benutzer und in zweiter Linie für Compiler (und wenn es um Benutzer geht, entwerfen wir zuerst zum Lesen und in zweiter Linie zum Schreiben).

    – Brian Götz

    18. April 2019 um 19:50 Uhr

Benutzer-Avatar
Saurab Gaur

In Java 8 wird ein neues Konzept namens Standardmethoden eingeführt. Standardmethoden sind solche Methoden, die eine Standardimplementierung haben und bei der Entwicklung der Schnittstellen helfen, ohne den vorhandenen Code zu beschädigen. Schauen wir uns ein Beispiel an:

public interface SimpleInterface {
    public void doSomeWork();

    //A default method in the interface created using "default" keyword

    default public void doSomeOtherWork() {
        System.out.println("DoSomeOtherWork implementation in the interface");
    }
}

class SimpleInterfaceImpl implements SimpleInterface {

    @Override
    public void doSomeWork() {
        System.out.println("Do Some Work implementation in the class");
    }

    /*
    * Not required to override to provide an implementation
    * for doSomeOtherWork.
    */

    public static void main(String[] args) {
        SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
        simpObj.doSomeWork();
        simpObj.doSomeOtherWork();
    }
}

und die Ausgabe ist:

   Do Some Work implementation in the class
   DoSomeOtherWork implementation in the interface

  • Wir müssen nicht überschreiben. Dies ist der entscheidende Punkt. Dies hilft mir, die Bearbeitung von N-Dateien mit meiner neuen Funktion zu vermeiden. Danke für das Beispiel!

    – Geoff Langenderfer

    25. Oktober 2021 um 15:34 Uhr

  • Frage: Was bewirkt diese Annotation @Override, wenn die unmittelbar übergeordnete Klasse tatsächlich eine Schnittstelle ist? Ist das überhaupt für die ersten Kinder von Interfaces erforderlich?

    – Navderm

    25. Februar um 21:58 Uhr

Benutzer-Avatar
Makoto

Etwas, das in den anderen Antworten übersehen wurde, war seine Rolle in Anmerkungen. So weit zurück wie Java 1.5, die default Schlüsselwort entstand als Mittel dazu geben Sie einen Standardwert an für ein Anmerkungsfeld.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Processor {
    String value() default "AMD";
}

Es war überladen mit der Einführung von Java 8, um eine Standardmethode in Schnittstellen zu definieren.

Etwas anderes, das übersehen wurde: der Grund für die Erklärung default class MyClass {} ungültig ist, liegt daran, dass Klassen werden überhaupt deklariert. Es gibt keine Bestimmung in der Sprache, die es zulässt, dass dieses Schlüsselwort dort erscheint. Es tut erscheinen für Deklarationen von Schnittstellenmethodenobwohl.

Standardmethoden in einer Schnittstelle ermöglichen es uns, neue Funktionen hinzuzufügen, ohne alten Code zu beschädigen.

Wenn vor Java 8 einer Schnittstelle eine neue Methode hinzugefügt wurde, mussten alle Implementierungsklassen dieser Schnittstelle diese neue Methode überschreiben, selbst wenn sie die neue Funktionalität nicht verwendeten.

Mit Java 8 können wir die Standardimplementierung für die neue Methode hinzufügen, indem wir die verwenden default Schlüsselwort vor der Methodenimplementierung.

Selbst bei anonymen Klassen oder funktionalen Schnittstellen können wir, wenn wir sehen, dass ein Teil des Codes wiederverwendbar ist und wir nicht überall im Code dieselbe Logik definieren möchten, Standardimplementierungen davon schreiben und sie wiederverwenden.

Beispiel

public interface YourInterface {
    public void doSomeWork();

    //A default method in the interface created using "default" keyword
    default public void doSomeOtherWork(){

    System.out.println("DoSomeOtherWork implementation in the interface");
       }
    }

    class SimpleInterfaceImpl implements YourInterface{

     /*
     * Not required to override to provide an implementation
     * for doSomeOtherWork.
     */
      @Override
      public void doSomeWork() {
  System.out.println("Do Some Work implementation in the class");
   }

 /*
  * Main method
  */
 public static void main(String[] args) {
   SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
   simpObj.doSomeWork();
   simpObj.doSomeOtherWork();
      }
   }

Das neue Java 8 Besonderheit (Standardmethoden) ermöglicht es einer Schnittstelle, eine Implementierung bereitzustellen, wenn sie mit dem gekennzeichnet ist default Stichwort.

Zum Beispiel:

interface Test {
    default double getAvg(int avg) {
        return avg;
    }
}
class Tester implements Test{
 //compiles just fine
}

Schnittstellentest verwendet das Standardschlüsselwort, das es der Schnittstelle ermöglicht, eine Standardimplementierung der Methode bereitzustellen, ohne dass diese Methoden in den Klassen implementiert werden müssen, die die Schnittstelle verwenden.

Rückwärtskompatibilität:
Stellen Sie sich vor, dass Ihre Schnittstelle von Hunderten von Klassen implementiert wird. Wenn Sie diese Schnittstelle ändern, werden alle Benutzer gezwungen, die neu hinzugefügte Methode zu implementieren, obwohl dies für viele andere Klassen, die Ihre Schnittstelle implementieren, nicht unbedingt erforderlich ist.

Fakten & Einschränkungen:

1-Kann nur innerhalb einer Schnittstelle und nicht innerhalb einer Klasse oder abstrakten Klasse deklariert werden.

2-Muss einen Körper bereitstellen

3-Es wird nicht angenommen, dass es öffentlich oder abstrakt ist wie andere normale Methoden, die in einer Schnittstelle verwendet werden.

Benutzer-Avatar
Riyafa Abdul Hameed

Eine sehr gute Erklärung findet sich in Die Java™-Tutorialsein Teil der Erklärung lautet wie folgt:

Betrachten Sie ein Beispiel, das Hersteller von computergesteuerten Autos betrifft, die Schnittstellen nach Industriestandard veröffentlichen, die beschreiben, welche Methoden aufgerufen werden können, um ihre Autos zu betreiben. Was wäre, wenn diese computergesteuerten Autohersteller ihren Autos neue Funktionen wie Flugfunktionen hinzufügen würden? Diese Hersteller müssten neue Methoden spezifizieren, um es anderen Unternehmen (z. B. Herstellern elektronischer Leitinstrumente) zu ermöglichen, ihre Software an fliegende Autos anzupassen. Wo würden diese Autohersteller diese neuen flugbezogenen Methoden deklarieren? Wenn sie sie zu ihren ursprünglichen Schnittstellen hinzufügen, müssten Programmierer, die diese Schnittstellen implementiert haben, ihre Implementierungen neu schreiben. Wenn sie sie als statische Methoden hinzufügen, würden Programmierer sie als nützliche Methoden und nicht als wesentliche Kernmethoden betrachten.

Mit Standardmethoden können Sie den Schnittstellen Ihrer Bibliotheken neue Funktionen hinzufügen und die Binärkompatibilität mit Code sicherstellen, der für ältere Versionen dieser Schnittstellen geschrieben wurde.

1016860cookie-checkWas ist der Zweck des Standardschlüsselworts in Java?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy