Java: Как избежать устаревшего предупреждения в производных интерфейсах, которые переопределяют устаревшие элементы? - PullRequest
12 голосов
/ 31 июля 2009

Рассмотрим следующую упрощенную иерархию наследования интерфейса:

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

public interface Derived extends Base {
}

Он предназначен для перемещения метода Foo из интерфейса Base в интерфейс Derived:

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

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

Для поэтапного внесения этих критических изменений желательно некоторое время поддерживать обратную совместимость интерфейса Base.

Этого можно достичь, пометив метод на интерфейсе Base как @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(); 
}

Когда я компилирую этот код, я получаю предупреждение компилятора для Derived:

[не рекомендуется] Foo () в интерфейсе Base устарела

Как ни странно, если я уберу @deprecated из документации в Base (но оставлю @Deprecated), это предупреждение исчезнет.

Правильно ли, что я получаю это предупреждение, и если да, как я могу обойти это?


Похоже, предупреждение говорит о том, что Derived.Foo «использует» Base.Foo (что устарело). Но единственная емкость, в которой Derived.Foo «использует» устаревший Base.Foo, - это переопределение. Это говорит о том, что вы не можете переопределять устаревшие методы интерфейса в производных методах.

Если это так, то должен ли я украсить Derived с помощью @SuppressWarnings("deprecation"), чтобы подавить предупреждение?

Ответы [ 4 ]

10 голосов
/ 01 августа 2009

Я считаю, что ваше требование действительно, я не сомневаюсь, что переопределение устаревшего метода - правильный путь.

Я считаю, что разница между @deprecated и @Deprecated в основном историческая. @Deprecated является официальным способом в Java 5, но является новым, поэтому мы должны удвоить его с @deprecated.

Также обратите внимание, что, к сожалению, @Deprecated не позволяет вам указывать информацию ... в то время как информация обычно требуется, например, чтобы указать, что следует использовать в качестве замены, или когда устаревший метод, как ожидается, будет полностью удален .

Не зная больше, и зная, что проблема исчезнет, ​​как только вы эффективно удалите метод super, я бы использовал @SuppressWarnings ("deprecation"), возможно, с комментарием, чтобы ваши преемники могли понять ... (и другое прокомментируйте метод super, чтобы они удалили все это при удалении метода). ; -)

3 голосов
/ 04 февраля 2016

Если вы добавите @Deprecated к производному объявлению Foo (), я думаю, предупреждение исчезнет.

public interface Derived extends Base {
    @Deprecated void Foo(); 
}
3 голосов
/ 31 июля 2009

если я правильно понимаю, вам нужен @SuppressWarnings («не рекомендуется») в начале ваших классов, которые реализуют устаревший интерфейс / функцию Или я здесь далеко от базы?

0 голосов
/ 04 августа 2009

Нет способа выполнить то, что вы хотите.

Устаревание является относительно простым механизмом и не поддерживает этот вариант использования.

Способ устаревания работает так, что все, что ссылается на устаревший метод или поле, генерирует предупреждение.

Единственное исключение - если сам код, использующий устаревший метод / поле, устарел.

...