2009-07-31 5 views
12

Betrachten Sie die folgende vereinfachte Schnittstelle inheritence Hierarchie:Java: Wie kann man veraltete Warnungen in abgeleiteten Schnittstellen vermeiden, die veraltete Elemente außer Kraft setzen?

// Starting point: 
public interface Base { 
    void Foo(); 
} 

public interface Derived extends Base { 
} 

Es ist beabsichtigt, die Foo Methode aus der Base Schnittstelle zum Derived Schnittstelle zu verschieben:

// Desired end-point: 
public interface Base { 
} 

public interface Derived extends Base { 
    void Foo(); 
} 

Um Phase in diesem unterbrechende Änderung, Es ist erwünscht, die Rückwärtskompatibilität der Schnittstelle für einige Zeit beizubehalten.

Dies kann durch Markieren des Verfahrens auf der Base Schnittstelle als @Deprecated erreicht werden:

// Intermediate state: 
public interface Base { 
    /** 
    * @deprecated This method is deprecated as of release X. Derived.Foo should be used instead. 
    */ 
    @Deprecated void Foo(); 
} 

public interface Derived extends Base { 
    void Foo(); 
} 

Wenn ich diesen Code, den ich eine Compiler-Warnung für Derived erhalten kompilieren:

[deprecation] Foo() in der Schnittstelle Base wurde veraltet

Seltsamerweise, wenn ich die @deprecated aus der Dokumentation in Base entfernen (aber die @Deprecated verlassen) diese Warnung verschwindet.

Ist es richtig, dass ich diese Warnung bekomme, und wenn ja, wie kann ich das umgehen?


Die Warnung scheint, dass Derived.Foo wird "mit" Base.Foo zu kommunizieren (die veraltet ist). Die einzige Kapazität, in der Derived.Foo die veraltete Version Base.Foo "verwendet", besteht darin, sie zu überschreiben. Das scheint zu sagen, dass es Ihnen nicht erlaubt ist, veraltete Methoden in abgeleiteten Methoden zu überschreiben.

Wenn dies der Fall ist, sollte ich dann Derived mit @SuppressWarnings("deprecation") verzieren, um die Warnung zu unterdrücken?

+0

Welche Java-Version verwenden Sie? Ich erinnere mich, dass dies zu einem bestimmten Zeitpunkt als Fehler angesehen wurde, möglicherweise behoben ... aber ich kann mir nicht sicher sein, ob ich mich richtig daran erinnere. Ich habe genau gesehen, was du meinst. –

Antwort

9

Ich glaube, Ihre Anforderung ist gültig, ich habe keinen Zweifel, dass das Überschreiben der veralteten Methode der richtige Weg ist.

Ich glaube, der Unterschied zwischen @deprecated und @Deprecated ist hauptsächlich historisch. @Deprecated ist der offizielle Weg in Java 5, aber ist neu, also wird erwartet, dass wir es mit @deprecated verdoppeln.

Beachten Sie außerdem, dass @Deprecated leider keine Informationen angeben kann. Informationen werden normalerweise benötigt, um beispielsweise anzugeben, was als Ersatz verwendet werden soll oder wann die veraltete Methode vollständig ausgeführt werden soll entfernt.

Nicht mehr zu wissen, und das Problem wird verschwinden, sobald Sie die Super-Methode effektiv entfernen, würde ich die @SuppressWarnings ("Deprecation") verwenden, möglicherweise mit einem Kommentar für Ihre Nachfolger zu verstehen ... (und ein weiterer Kommentar zur super-Methode, um ihnen zu sagen, dass sie alles löschen sollen, wenn sie die Methode löschen.;-)

2

Wenn ich das richtig verstehe, benötigen Sie am Anfang Ihrer Klassen ein @SuppressWarnings ("deprecation"), das die veraltete Schnittstelle/Funktion implementiert. Oder bin ich weit weg von der Basis?

+0

Das klingt vernünftig, aber das Problem hier ist, dass es keine implementierenden Klassen gibt. Nur die zwei Schnittstellen. Die Warnung scheint zu kommunizieren, dass "Derived.Foo" "Base.Foo" verwendet (was veraltet ist). Aber die einzige Kapazität, in der "Derived.Foo" das veraltete "Base.Foo" "verwendet", besteht darin, es zu überschreiben. Das scheint zu sagen, dass es Ihnen nicht erlaubt ist, veraltete Methoden in abgeleiteten Methoden zu überschreiben. Ist das vernünftig? –

+0

Ich weiß nicht über "nicht erlaubt", aber da Sie tatsächlich eine veraltete Funktion außer Kraft setzen, erscheint es mir vernünftig, dass es sich darüber beschweren würde. Gibt es eine Möglichkeit, sie zu entkoppeln und sie zwei völlig getrennte Schnittstellen zu haben oder muss Abgeleitet für andere Funktionalität erweitert werden? – MattC

-1

Es gibt keine Möglichkeit zu erreichen, was Sie wollen.

Die Verschrottung ist ein relativ einfacher Mechanismus und unterstützt diesen Anwendungsfall nicht.

Die Vorgehensweise bei der Verwendung von Deprecation besteht darin, dass bei einer Verweisung auf eine veraltete Methode oder ein Feld eine Warnung generiert wird.

Die einzige Ausnahme ist, wenn der Code, der die veraltete Methode/das veraltete Feld verwendet, selbst veraltet ist.

+0

Und das ist die richtige Reaktion (anstatt die Warnung zu unterdrücken), weil Sie in abgeleiteter Methode auf veraltete APIs vertrauen. – Mnementh

+0

Der Punkt der Einführung der Methode auf 'Derived' ist, die Methode von 'Base' zu 'Derived' zu migrieren, daher möchte ich die Methode auf' Base' verwerfen und die Dokumentation" diese Methode für 'Derived' verwenden" . Es macht keinen Sinn, die (neu hinzugefügte) Methode in diesem Szenario abzulehnen. –

+0

Deshalb habe ich gesagt "unterstützt diesen Anwendungsfall nicht" –

3

Wenn Sie @Deprecated zu Ihrer abgeleiteten Deklaration von Foo() hinzufügen, glaube ich, dass die Warnung verschwindet.

public interface Derived extends Base { 
    @Deprecated void Foo(); 
} 
+0

Dies sollte die akzeptierte Antwort sein. –

Verwandte Themen