2009-07-31 6 views
12

consideri il seguente gerarchia interfaccia inheritence semplificata:Java: come evitare l'avviso deprecato nelle interfacce derivate che sovrascrivono i membri deprecati?

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

public interface Derived extends Base { 
} 

Si intende spostare il metodo Foo dall'interfaccia Base all'interfaccia Derived:

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

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

Per fase in questo cambiamento di rottura, si desidera mantenere la compatibilità all'indietro dell'interfaccia Base per un po 'di tempo.

Ciò può essere ottenuto marcando il metodo sull'interfaccia Base come @Deprecated:

// 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(); 
} 

Quando compilo questo codice ricevo un avviso del compilatore per Derived:

[deprecazione] Foo() nell'interfaccia La base è stata deprecata

Stranamente, se rimuovo lo @deprecated dalla documentazione in Base (ma lascia il @Deprecated) questo avviso scompare.

È corretto che venga visualizzato questo avviso e, in caso affermativo, come posso risolvere il problema?


L'avvertimento sembra comunicare che Derived.Foo sta "utilizzando" Base.Foo (che è deprecato). Ma l'unica capacità in cui Derived.Foo "sta usando" il deprecato Base.Foo è di sovrascriverlo. Ciò sembra dire che non è consentito sovrascrivere i metodi di interfaccia deprecati nei metodi derivati.

Se questo è il caso, dovrei quindi decorare Derived con @SuppressWarnings("deprecation") per sopprimere l'avviso?

+0

Quale versione di Java stai utilizzando? Mi sembra di ricordare che a un certo punto è stato considerato un bug, probabilmente risolto ... ma non posso essere sicuro di averlo ricordato correttamente. Ho visto esattamente cosa intendi. –

risposta

9

Credo che la vostra esigenza è valida, non ho alcun dubbio che l'override del metodo deprecato è il modo corretto di andare.

credo che la differenza tra @deprecated e @deprecated è prevalentemente storico. @Deprecated è il modo ufficiale in java 5, ma è nuovo, quindi ci aspettiamo di raddoppiarlo con @deprecated.

Si noti inoltre che, purtroppo, @Deprecated non consente di specificare le informazioni .. mentre di solito sono necessarie le informazioni, ad esempio per indicare cosa deve essere utilizzato come sostituzione o quando si prevede che il metodo deprecato sia completamente rimosso.

Non sapendo più, e conoscendo il problema scompare non appena si rimuove in modo efficace il metodo super, vorrei utilizzare le @SuppressWarnings ("disapprovazione"), possibilmente con un commento per i tuoi successori di capire ... (e un altro commento sul metodo super per dire loro di rimuovere tutto ciò quando si elimina il metodo).;-)

2

se ho capito bene, hai bisogno di una @SuppressWarnings ("deprecazione") all'inizio delle classi che implementano l'interfaccia/funzione di deprecato. O vado via di base qui?

+0

Sembra ragionevole, tuttavia il problema qui è che non ci sono classi di implementazione. Solo le due interfacce. L'avvertimento sembra comunicare che "Derived.Foo' sta" usando "' Base.Foo' (che è deprecato). Ma l'unica capacità in cui "Derived.Foo' sta" usando "il deprecato' Base.Foo' è di sovrascriverlo. Ciò sembra dire che non è consentito sovrascrivere i metodi di interfaccia deprecati nei metodi derivati. È ragionevole? –

+0

Non so "non consentito", ma poiché in effetti si sta ignorando una funzione deprecata mi sembra ragionevole lamentarsi di ciò. C'è un modo per disaccoppiarli e farli essere due interfacce completamente separate o Derived devono estendersi per altre funzionalità? – MattC

-1

Non c'è modo di realizzare ciò che vuoi.

La deprecazione è un meccanismo relativamente semplice e non supporta questo caso d'uso.

Il modo in cui funziona la deprecazione è che qualsiasi cosa che fa riferimento a un metodo o campo deprecato genera un avviso.

L'unica eccezione è se il codice che utilizza il metodo/campo deprecato è deprecato.

+0

E questa è la reazione corretta (invece di sopprimere l'avviso), perché si fa affidamento sul proprio metodo derivato su API deprecate. – Mnementh

+0

Il punto di introdurre il metodo su "Derivato" è migrare il metodo da "Base" a "Derivato", quindi voglio deprecare il metodo su "Base" e fornire la documentazione che dice "usa questo metodo su" Derivato "" . Non ho senso deprecare il metodo (appena aggiunto) su "Derivato" in questo scenario. –

+0

Ecco perché ho detto "non supporta questo caso d'uso" –

3

Se si aggiunge @Deprecated alla dichiarazione derivata di Foo(), credo che l'avviso scomparirà.

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

Questa dovrebbe essere la risposta accettata. –