Устарело только наследование классов

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

То есть предупреждение появится, если вы расширите данный класс, но ссылки на методы или поля не вызовут предупреждения. Уже есть несколько классов, которые расширяют этот класс, и я хочу, чтобы предупреждения об устаревании были нацелены на этих клиентов — я пока не могу их сломать (но их можно перекомпилировать — совместимость с ABI не требуется).

Возможно ли это в Java 1.6 (компилятор JDT)?


person BeeOnRope    schedule 14.02.2011    source источник
comment
В качестве обновления с учетом ответов до сих пор - мне нужно разрешить классам продолжать расширять класс, поскольку я еще не могу удалить зависимость, но я хочу, чтобы они получали предупреждения об устаревании при этом.   -  person BeeOnRope    schedule 14.02.2011
comment
Спасибо за ответы. В конце концов, ни одно из приведенных ниже решений не было полностью адекватным (использование final не является стартовым, потому что я хочу предупредить, а не сломать), поэтому я решил отказаться от защищенных конструкторов, которые должны использовать подклассы, которые имели аналогичный эффект (одно предупреждение об устаревании для каждого расширения).   -  person BeeOnRope    schedule 21.02.2011


Ответы (5)


Два соображения

1) Возможно, класс уже расширен, поэтому не отмечайте его как окончательный, иначе вы можете нарушить обратную совместимость.

2) Вы не хотите, чтобы класс расширялся, поэтому он должен быть помечен как окончательный.

Я думаю, вам следует расширить старый класс новым классом, пометить старый класс как устаревший и объявить новый класс окончательным. В новом классе вы можете добавить тег @SuppressWarning, чтобы отключить устаревшее сообщение, тогда вы должны получить чистую компиляцию.

Код, использующий старый класс, получит предупреждение @Deprecated, но все равно будет скомпилирован. Код, использующий новый класс, будет компилироваться корректно. Своего рода «сильное предложение» для ваших пользователей вместо разрыва с обратной совместимостью, и им довольно легко исправить, поскольку API на 100% совместим.

person Zak    schedule 14.02.2011
comment
Пометка этого ответа, как это чаще всего мне нужно, - способ предупредить потребителей о расширении класса, фактически не нарушая их и не предупреждая о каждом вызове метода. - person BeeOnRope; 21.02.2011

Сомневаюсь, что это возможно с помощью аннотации @Deprecated.

Однако, если у вас есть контроль над источниками, вы можете сделать следующее:

  1. Переименуйте текущий класс SomeClass в SomeClassSuper
  2. Создайте новый класс с именем SomeClass и дайте ему расширить SomeClassSuper.
  3. Сделать SomeClass окончательным (что не позволит клиентам расширить его).

То есть идти от

class SomeClass {
    // ...
}

class SubClass extends SomeClass {
    // ...
}

to

class SomeClassSuper {
    // ...
}

class SubClass extends SomeClassSuper {
    // ...
}

final class SomeClass extends SomeClassSuper {
    // ...
}
person aioobe    schedule 14.02.2011

Нет, ни за что. Вы можете сделать класс final, но тем самым вы нарушите существующие расширения.

Возможно, это возможно путем разработки собственного процессора для APT. Но в общем случае он не будет применяться.

person Bozho    schedule 14.02.2011

Если это соответствует вашему дизайну, вы, возможно, могли бы сделать необходимые функции (например, конструкторы, к которым должны получить доступ потомки) закрытыми и предоставить защищенный + устаревший конструктор, который необходимо будет использовать расширениям.

person Erik    schedule 14.02.2011

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

person josefx    schedule 14.02.2011