Разница между аннотациями объявлений и аннотациями типов

Java 8 представила аннотации типов с JSR308. Согласно спецификациям языка Java

аннотации типа можно использовать везде, где используется тип, например, в объявлениях, общих аргументах, приведениях и т. д.

Я относительно новичок в Java, Java 8 была первой версией Java, которую я использовал, поэтому я не знаком с аннотациями, не относящимися к типам, то есть с аннотациями объявлений.

Чем аннотации объявлений отличаются от аннотаций типов? Я хочу знать, потому что я постоянно слышу о них в руководствах, и похоже, что «аннотации типов» являются надмножеством «аннотаций объявлений».


person saga    schedule 01.05.2018    source источник


Ответы (2)


И аннотации типов, и аннотации объявлений все еще существуют в Java, и они различны и не пересекаются.

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

Например, тип int содержит значения ..., -2, -1, 0, 1, 2, ...
Тип @Positive int содержит значения 1, 2, ...
Следовательно, @Positive int является подтип int.

Аннотация объявления может быть написана для любого объявления (класса, метода или переменной). Он описывает объявляемую вещь, но не описывает значения времени выполнения. Вот примеры аннотаций объявлений:

@Deprecated
class MyClass { ... }

говорит, что программисты не должны использовать MyClass.

@Override
void myMethod() { ... }

говорит, что myMethod переопределяет объявление в суперклассе или интерфейсе.

@SuppressWarnings(...)
int myField = INITIALIZATION-EXPRESSION;

говорит, что компилятор не должен выдавать предупреждения о коде в выражении инициализации.

Вот примеры, которые используют как аннотацию объявления, так и аннотацию типа:

@Override
@NonNull String myMethod() { ... }

@GuardedBy("myLock")
@Regex String myField;

Обратите внимание, что аннотация типа описывает значение, а аннотация объявления что-то говорит о методе или использовании поля.

Из соображений стиля аннотации объявлений пишутся на отдельной строке, а аннотации типа пишутся непосредственно перед типом на той же строке.

person mernst    schedule 02.05.2018

Большинство аннотаций сейчас являются аннотациями объявлений, например @Override:

class Foo implements Runnable {
    @Override // applies to the declaration of Foo.run()
    public void run() {
    }
}

Аннотации типов расширяют возможные цели аннотаций для использования типов, которые не являются объявлениями (приведения, аргументы типа и т. д.). Аннотации типов могут появляться в объявлениях, но аннотации типов не являются надмножеством аннотаций объявлений. Например, @Override никогда не является аннотацией типа.

В неоднозначных случаях, например @Foo int x;, JLS §9.7.4 описывает конкретные правила, определяющие, является ли объявление или тип аннотированным. В некоторых случаях это даже считается и тем, и другим.

Ниже приведены несколько однозначных примеров аннотаций типов:

// cast
String str = (@Foo String) take();
// type argument
List<@Foo String> list = new ArrayList<>();

Полагаю, я мог бы также добавить, что проблема с аннотациями типов на данный момент заключается в том, что нет официального API, который позволяет обработчику аннотаций (в основном подключаемому модулю компилятора) делать с ними что-либо значимое. В результате аннотации типов обычно используются только сторонними инструментами, такими как Lombok и компилятор Eclipse.

person Radiodef    schedule 01.05.2018