2010-09-29 4 views
10

Während mit Anmerkungen arbeitet ich auf dem anderen folgende Stück Code gestolpert (es ist die Hibernate @NotNull Anmerkung):Standardmethode Rückgabewert in Java-Schnittstellen

@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER}) 
@Retention(value = RetentionPolicy.RUNTIME) 
@Documented 
@Constraint(validatedBy = {}) 
public @interface NotNull { 

    @Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER}) 
    @Retention(value = RetentionPolicy.RUNTIME) 
    @Documented 
    public @interface List { 

     public NotNull[] value(); 
    } 

    public String message() default "{javax.validation.constraints.NotNull.message}"; 

    public Class<?>[] groups() default {}; 

    public Class<? extends Payload>[] payload() default {}; 
} 

Ich frage mich, über das default Schlüsselwort/in dem Verfahren konstruieren Definition, die ich noch nie zuvor gesehen habe. Wie ich verstanden habe, können Sie einen Standardwert für diese Methode (oder Annotationseigenschaft) definieren.

Jetzt habe ich versucht, dieses Konstrukt auf eine normale Schnittstelle anzuwenden, aber es ist fehlgeschlagen. Dies würde nicht kompiliert:

public interface DefaultTest { 
    public String test() default "value"; 
} 

Aber dies funktionieren würde:

public @interface DefaultTest { 
    public String test() default "value"; 
} 

Also meine Frage ist: Ist das default Stichwort Annotation-spezifisch? Und wenn ja, was spricht dagegen, dieses Konstrukt in normalen Schnittstellendefinitionen zu verwenden?

Antwort

16

Java 8 und weiter

Ja, das Standard-Schlüsselwort nun auf Schnittstellen verwendet werden. Für weitere Details siehe Oracle's docs.

Die Implementierung ist etwas anders als das, was Sie dachten. Es wäre:

public interface DefaultTest { 
    default public String test() { 
     return "value"; 
    } 
} 

Java 7 und früheren

Der Standard Schlüsselwort kann nur für Anmerkungen verwendet werden.

Wenn Sie einen Standard-Rückgabewert für eine Schnittstelle wünschen, müssen Sie stattdessen eine abstrakte Klasse verwenden.

public abstract class DefaultTest { 

    public String test() { 
    return "value"; 
    } 

} 
+1

Die Mehrfachschnittstellenvererbung macht absolut Sinn. Danke, dass du darauf hingewiesen hast. – MicSim

+0

stellte sich heraus, Sie tatsächlich prescient waren. 8 Java jetzt können Sie tun, was Sie wollen! Ich habe meine Antwort aktualisiert. – Pace

3

Das Schlüsselwort 'default' ist hier nicht anmerkungsspezifisch. Es ist die Eigenschaft von Java, Standard-Implementierung zu Interface-Methoden bereitzustellen.

Notwendigkeit dieses Verhalten: Angenommen, zunächst ein Schnittstelle Fahrzeug definiert wurde, um alle Fahrzeuge funktionale Methoden zu unterstützen -

interface Vehicle { 
    void speed(); 

    ... 
    //other interface methods 
} 

Jetzt Klassen Diese Fahrzeug-Schnittstelle dieser abstrakten Methoden implementiert umzusetzen.

Jetzt in Zukunft Fahrzeug Fähigkeit des Fliegens. Sie müssen also auch die Flugfunktion hinzufügen. Wenn Sie die fliehSpeed ​​() - Methode jetzt zur Vehicle-Schnittstelle hinzufügen, müssen Sie alle vorhandenen Klassen ändern, um zu vermeiden, dass der Code bricht. Nicht durchführbare Lösung.

Aus Gründen der Abwärtskompatibilität bietet Java die Funktion der Standardmethode. So können Sie neue Methoden hinzufügen, um eine Schnittstelle zur Standardimplementierung zu erstellen, sodass die vorhandenen Klassen diese Methode nicht implementieren müssen. Und die neuen Fahrzeugklassen können diese Methoden je nach Bedarf überschreiben.

interface Vehicle { 
    void speed(); 

    ... 
    //other interface methods 

    //default method 
    default void flyingSpeed() { 
    System.out.println("Default flying speed"); 
    } 
} 

Auf diese Weise müssen vorherige Klassen des Fahrzeugs diese Methode nicht implementieren.

Weitere Informationen see hier.