Рубрики
Без рубрики

Java Аннотации Вопросы для интервью (+ Ответы)

Набор популярных аннотаций Java, вопросы для интервью и, конечно же, ответы.

Автор оригинала: baeldung.

1. введение

Аннотации существуют с Java 5, и в настоящее время они являются вездесущими конструкциями программирования, которые позволяют обогащать код.

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

2. Вопросы

Q1. Что Такое Аннотации? Каковы Их Типичные Случаи Использования?

Аннотации-это метаданные, привязанные к элементам исходного кода программы и не влияющие на работу кода, с которым они работают.

Их типичными случаями использования являются:

  • Информация для компилятора – с помощью аннотаций компилятор может обнаруживать ошибки или подавлять предупреждения
  • Обработка во время компиляции и развертывания -программные средства могут обрабатывать аннотации и генерировать код, файлы конфигурации и т. Д.
  • Обработка во время выполнения – аннотации могут быть проверены во время выполнения, чтобы настроить поведение программы

Q2. Опишите некоторые полезные аннотации из Стандартной библиотеки.

В пакетах java.lang и java.lang.annotation имеется несколько аннотаций, наиболее распространенные из которых включают, но не ограничиваются:

  • @Override – отмечает, что метод предназначен для переопределения элемента, объявленного в суперклассе. Если ему не удастся правильно переопределить метод, компилятор выдаст ошибку
  • @Deprecated – указывает, что элемент устарел и не должен использоваться. Компилятор выдаст предупреждение, если программа использует метод, класс или поле, отмеченные этой аннотацией
  • @SuppressWarnings – указывает компилятору подавлять определенные предупреждения. Наиболее часто используется при взаимодействии с устаревшим кодом, написанным до появления дженериков
  • @functional Interface – введено в Java 8, указывает, что объявление типа является функциональным интерфейсом и реализация которого может быть предоставлена с помощью лямбда-выражения

Q3. Как Вы можете Создать Аннотацию?

Аннотации-это форма интерфейса, в которой ключевому слову interface предшествует @, и тело которого содержит элемент типа аннотации объявления, которые очень похожи на методы:

public @interface SimpleAnnotation {
    String value();

    int[] types();
}

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

@SimpleAnnotation(value = "an element", types = 1)
public class Element {
    @SimpleAnnotation(value = "an attribute", types = { 1, 2 })
    public Element nextElement;
}

Обратите внимание, что при предоставлении нескольких значений для элементов массива их необходимо заключить в квадратные скобки.

При необходимости можно указать значения по умолчанию, если они являются постоянными выражениями для компилятора:

public @interface SimpleAnnotation {
    String value() default "This is an element";

    int[] types() default { 1, 2, 3 };
}

Теперь вы можете использовать аннотацию без этих элементов:

@SimpleAnnotation
public class Element {
    // ...
}

Или только некоторые из них:

@SimpleAnnotation(value = "an attribute")
public Element nextElement;

Q4. Какие Типы объектов Могут Быть Возвращены из Объявления Метода Аннотации?

Возвращаемый тип должен быть примитивом, Строкой , Классом , Перечислением или массивом одного из предыдущих типов. В противном случае компилятор выдаст ошибку.

Вот пример кода, который успешно следует этому принципу:

enum Complexity {
    LOW, HIGH
}

public @interface ComplexAnnotation {
    Class value();

    int[] types();

    Complexity complexity();
}

Следующий пример не удастся скомпилировать, так как Object не является допустимым типом возвращаемого значения:

public @interface FailingAnnotation {
    Object complexity();
}

Q5. Какие Элементы Программы Могут Быть Аннотированы?

Аннотации могут быть применены в нескольких местах по всему исходному коду. Они могут быть применены к объявлениям классов, конструкторов и полей:

@SimpleAnnotation
public class Apply {
    @SimpleAnnotation
    private String aField;

    @SimpleAnnotation
    public Apply() {
        // ...
    }
}

Методы и их параметры:

@SimpleAnnotation
public void aMethod(@SimpleAnnotation String param) {
    // ...
}

Локальные переменные, включая цикл и переменные ресурсов:

@SimpleAnnotation
int i = 10;

for (@SimpleAnnotation int j = 0; j < i; j++) {
    // ...
}

try (@SimpleAnnotation FileWriter writer = getWriter()) {
    // ...
} catch (Exception ex) {
    // ...
}

Другие типы аннотаций:

@SimpleAnnotation
public @interface ComplexAnnotation {
    // ...
}

И даже пакеты, через package-info.java файл:

@PackageAnnotation
package com.baeldung.interview.annotations;

Начиная с Java 8, они также могут быть применены к использованию типов. Для этого в аннотации необходимо указать @Target аннотацию со значением типа элемента .ИСПОЛЬЗОВАНИЕ :

@Target(ElementType.TYPE_USE)
public @interface SimpleAnnotation {
    // ...
}

Теперь аннотацию можно применить к созданию экземпляра класса:

new @SimpleAnnotation Apply();

Тип слепков:

aString = (@SimpleAnnotation String) something;

Реализует предложение:

public class SimpleList
  implements @SimpleAnnotation List<@SimpleAnnotation T> {
    // ...
}

И бросает предложение:

void aMethod() throws @SimpleAnnotation Exception {
    // ...
}

Q6. Есть ли способ ограничить Элементы, к которым может быть применена Аннотация?

Да, для этой цели можно использовать аннотацию @Target . Если мы попытаемся использовать аннотацию в контексте, где она неприменима, компилятор выдаст ошибку.

Вот пример ограничения использования аннотации @SimpleAnnotation только объявлениями полей:

@Target(ElementType.FIELD)
public @interface SimpleAnnotation {
    // ...
}

Мы можем передать несколько констант, если хотим, чтобы это было применимо в большем количестве контекстов:

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PACKAGE })

Мы даже можем сделать аннотацию, чтобы ее нельзя было использовать для аннотирования чего-либо. Это может пригодиться, когда объявленные типы предназначены исключительно для использования в качестве типа-члена в сложных аннотациях:

@Target({})
public @interface NoTargetAnnotation {
    // ...
}

Q7. Что Такое Мета-Аннотации?

Являются аннотациями, которые применяются к другим аннотациям.

Все аннотации, которые не помечены @Target, или помечены им, но включают ANNOTATION_TYPE constant, также являются мета-аннотациями:

@Target(ElementType.ANNOTATION_TYPE)
public @interface SimpleAnnotation {
    // ...
}

Q8. Что Такое Повторяющиеся Аннотации?

Это аннотации, которые могут быть применены несколько раз к одному и тому же объявлению элемента.

По соображениям совместимости, поскольку эта функция была введена в Java 8, повторяющиеся аннотации хранятся в аннотации контейнера , которая автоматически генерируется компилятором Java. Для компилятора, чтобы сделать это, есть два шага, чтобы объявить их.

Во-первых, нам нужно объявить повторяющуюся аннотацию:

@Repeatable(Schedules.class)
public @interface Schedule {
    String time() default "morning";
}

Затем мы определяем содержащую аннотацию с обязательным элементом value , тип которого должен быть массивом повторяющегося типа аннотации:

public @interface Schedules {
    Schedule[] value();
}

Теперь мы можем использовать @Schedule несколько раз:

@Schedule
@Schedule(time = "afternoon")
@Schedule(time = "night")
void scheduledMethod() {
    // ...
}

Q9. Как Вы Можете Получить Аннотации? Как это связано с Его Политикой хранения?

Для получения аннотаций можно использовать API отражения или процессор аннотаций.

Аннотация @Retention и ее параметр Политика хранения влияют на то, как вы можете их получить. В RetentionPolicy перечислении есть три константы:

  • Политика удержания.SOURCE – делает аннотацию отброшенной компилятором, но обработчики аннотаций могут их прочитать
  • Политика удержания.CLASS – указывает, что аннотация добавлена в файл класса, но недоступна через отражение
  • Политика удержания.RUNTIME –Аннотации записываются компилятором в файл класса и сохраняются JVM во время выполнения, чтобы их можно было читать рефлексивно

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

@Retention(RetentionPolicy.RUNTIME)
public @interface Description {
    String value();
}

Теперь аннотации можно получить с помощью отражения:

Description description
  = AnnotatedClass.class.getAnnotation(Description.class);
System.out.println(description.value());

Обработчик аннотаций может работать с Политикой хранения .ИСТОЧНИК , это описано в статье Обработка аннотаций Java и создание конструктора .

Политика удержания.КЛАСС можно использовать, когда вы пишете анализатор байт-кода Java.

Q10. Будет ли Компилироваться Следующий Код?

@Target({ ElementType.FIELD, ElementType.TYPE, ElementType.FIELD })
public @interface TestAnnotation {
    int[] value() default {};
}

Нет. Это ошибка времени компиляции, если одна и та же константа перечисления появляется более одного раза в аннотации @Target .

Удаление повторяющейся константы приведет к успешной компиляции кода:

@Target({ ElementType.FIELD, ElementType.TYPE})

Q11. Можно ли расширить аннотации?

Нет. Аннотации всегда расширяются java.lang.annotation.Аннотация, как указано в спецификации языка Java .

Если мы попытаемся использовать предложение extends в объявлении аннотации, мы получим ошибку компиляции:

public @interface AnAnnotation extends OtherAnnotation {
    // Compilation error
}

Вывод

В этой статье мы рассмотрели некоторые из часто задаваемых вопросов, возникающих в технических интервью для разработчиков Java, касающихся аннотаций. Это ни в коем случае не исчерпывающий список, и его следует рассматривать только как начало дальнейших исследований.

Мы, в Baeldung, желаем вам успехов в любых предстоящих интервью.