2009-07-31 13 views
12

Considérese la siguiente jerarquía interfaz inheritence simplificado:Java: ¿Cómo evitar las advertencias obsoletas en las interfaces derivadas que anulan los miembros obsoletos?

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

public interface Derived extends Base { 
} 

Se pretende mover el método Foo desde la interfaz de Base a la interfaz Derived:

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

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

Con el fin de fase en este cambio de última hora, se desea conservar la compatibilidad con versiones anteriores de la interfaz Base durante algún tiempo.

Esto se puede lograr marcando el método en la interfaz Base como @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(); 
} 

Cuando compilar este código recibo una advertencia del compilador para Derived:

[deprecation] Foo() en la interfaz Base ha quedado en desuso

Curiosamente, si elimino el @deprecated de la documentación en Base (pero dejo el @Deprecated) esta advertencia desaparece.

¿Es correcto que reciba esta advertencia y, de ser así, cómo puedo evitar esto?


La advertencia parece comunicar que Derived.Foo es "usar" Base.Foo (que está en desuso). Pero la única capacidad en la que Derived.Foo está "usando" el Base.Foo obsoleto es anularlo. Eso parece decir que no se te permite anular los métodos de interfaz en desuso en los métodos derivados.

Si este es el caso, ¿debo decorar Derived con para suprimir la advertencia?

+0

¿Qué versión de Java estás usando? Me parece recordar que esto fue considerado un error en algún momento, posiblemente arreglado ... pero no puedo estar seguro de recordar esto correctamente. He visto exactamente lo que quieres decir. –

Respuesta

9

Creo que su requisito es válido, no tengo ninguna duda de que anular el método en desuso es la forma correcta de hacerlo.

Creo que la diferencia entre @deprecated y @Deprecated es principalmente histórica. @Deprecated es la forma oficial en Java 5, pero es nueva, por lo que se espera que la dupliquemos con @deprecated.

También tenga en cuenta que, lamentablemente, @Deprecated no le permite especificar información ... mientras que generalmente se necesita información, por ejemplo, para decir qué se debe usar como reemplazo o cuando se espera que el método en desuso sea completamente remoto.

Sin saber más, y sabiendo que el problema desaparecerá tan pronto como elimine efectivamente el supermétodo, usaría @SuppressWarnings ("desaprobación"), posiblemente con un comentario para que entiendan sus sucesores ... (y otro comentario sobre el método súper para decirles que eliminen todo eso al eliminar el método).;-)

2

si entiendo correctamente, necesita @SuppressWarnings ("desaprobación") al comienzo de las clases que implementan la interfaz/función en desuso. ¿O estoy fuera de la base aquí?

+0

Eso suena razonable, sin embargo, el problema aquí es que no hay clases de implementación. Solo las dos interfaces. La advertencia parece comunicar que 'Derived.Foo' está" usando "' Base.Foo' (que está en desuso). Pero la única capacidad en la que 'Derived.Foo' está" usando "el' Base.Foo' en desuso es anularla. Eso parece decir que no se te permite anular los métodos de interfaz en desuso en los métodos derivados. Es esto razonable? –

+0

No sé "no permitido", pero como en realidad está anulando una función obsoleta, me parece razonable que se queje. ¿Hay alguna forma de desacoplarlos y hacer que sean dos interfaces completamente separadas o Derived debe extenderse para otras funcionalidades? – MattC

-1

No hay forma de lograr lo que quieres.

La depreciación es un mecanismo relativamente simple y no es compatible con este caso de uso.

La manera en que funciona la degradación es que cualquier cosa que haga referencia a un método o campo en desuso genera una advertencia.

La única excepción es si el código que usa el método/campo obsoleto está en desuso.

+0

Y esa es la reacción correcta (en lugar de suprimir la advertencia), porque confías en tu método derivado en las API obsoletas. – Mnementh

+0

El objetivo de introducir el método en 'Derived' es migrar el método de' Base' a 'Derived', por lo tanto, quiero desaprobar el método en' Base' y proporcionar documentación que diga "use this method on' Derived' " . No tiene sentido desaprobar el método (recién agregado) en 'Derived' en este escenario. –

+0

Por eso dije "no es compatible con este caso de uso" –

3

Si agrega @Deprecated a su declaración derivada de Foo(), creo que la advertencia desaparecerá.

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

Esta debería ser la respuesta aceptada. –

Cuestiones relacionadas