анотации

Аннотации в Java — это специальные метаданные, которые добавляются к классам, методам, полям и другим элементам программы. Они не влияют на сам код, но предоставляют информацию, которую можно использовать во время компиляции или выполнения программы. Основные цели аннотаций:

Упрощение кода: Аннотации могут заменить громоздкие конфигурации и настройки, делая код более читаемым и понятным.

Обработка на этапе компиляции: Некоторые аннотации могут быть использованы компилятором для проверки кода на наличие ошибок. Например, аннотация @Override указывает, что метод переопределяет метод суперкласса, и компилятор может выдать предупреждение, если это не так.

Время выполнения: Аннотации могут быть использованы фреймворками и библиотеками во время выполнения. Например, в Spring Framework аннотации, такие как @Autowired, используются для автоматической инъекции зависимостей.

Документация: Аннотации могут служить для генерации документации. Например, аннотация @Deprecated указывает, что метод устарел и не рекомендуется к использованию.

Примеры аннотаций:

@Override — указывает, что метод переопределяет метод суперкласса.
@Deprecated — указывает, что элемент устарел.
@SuppressWarnings — подавляет предупреждения компилятора.
@Entity — используется в JPA для обозначения класса как сущности базы данных.

Создание собственных аннотаций:

Вы также можете создавать свои собственные аннотации, определяя их с помощью ключевого слова @interface. Например:

public @interface MyAnnotation {
    String value();
}

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

Интерфейс с аннотацией в Java, также известный как аннотированный интерфейс, является расширением обычного интерфейса. Основное отличие аннотированного интерфейса от обычного заключается в том, что он позволяет добавлять дополнительную информацию, называемую аннотациями, к методам и полям интерфейса. Аннотации - это специальные метаданные, которые предоставляют контекстную информацию для компилятора, виртуальной машины Java (JVM) и других инструментов. Они используются для описания или модификации поведения кода, включая классы, методы, поля, параметры и т.д. Примеры аннотированных интерфейсов:

Интерфейс с аннотациями для спецификации API:

public interface MyAPI {
    @Deprecated
    void oldMethod();

    @Override
    @Nonnull
    String toString();
}

В этом примере аннотации @Deprecated и @Nonnull предоставляют дополнительную информацию о методах интерфейса.

  1. Интерфейс с аннотациями для внедрения зависимостей:
public interface UserService {
    @Inject
    void setDao(UserDao dao);

    void createUser(User user);
}

В этом примере аннотация @Inject указывает, что метод setDao() должен использоваться для внедрения зависимости UserDao.

Интерфейс с аннотациями для спецификации бизнес-правил:

public interface OrderProcessor {
    @CheckOrder
    boolean processOrder(Order order);

    @CheckInventory
    int getAvailableStock(Product product);
}

В этом примере аннотации @CheckOrder и @CheckInventory указывают на бизнес-правила, применяемые к методам интерфейса. Основные виды аннотаций в Java:

Стандартные аннотации Java (например, @Override, @Deprecated, @SuppressWarnings). Аннотации для внедрения зависимостей (например, @Inject, @Autowired). Аннотации для спецификации API (например, @Nonnull, @CheckForNull). Аннотации для управления ресурсами (например, @Resource, @PreDestroy). Аннотации для определения бизнес-правил (например, @ValidOrder, @CheckInventory). Пользовательские аннотации, определяемые разработчиком.

Аннотированные интерфейсы позволяют более четко и структурированно описывать API, управлять зависимостями, обеспечивать соблюдение бизнес-правил и т.д. Это делает код более самодокументируемым, улучшает переиспользование и поддержку.


@Retention и @Target - это две важные системные аннотации в Java, используемые при создании пользовательских аннотаций.

@Retention:

Эта аннотация определяет, на какой стадии жизненного цикла Java будет доступна ваша пользовательская аннотация. Она принимает один из трех возможных параметров:

RetentionPolicy.SOURCE: аннотация сохраняется только на уровне исходного кода, она игнорируется компилятором и JVM. RetentionPolicy.CLASS: аннотация сохраняется в скомпилированном классе, но недоступна во время выполнения. RetentionPolicy.RUNTIME: аннотация доступна во время выполнения и может быть прочитана с помощью рефлексии.

Пример:

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    // Аннотация доступна во время выполнения
}

@Target:

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

ElementType.TYPE: может использоваться на классах, интерфейсах, перечислениях. ElementType.FIELD: может использоваться на полях. ElementType.METHOD: может использоваться на методах. ElementType.PARAMETER: может использоваться на параметрах методов. ElementType.CONSTRUCTOR: может использоваться на конструкторах. ElementType.LOCAL_VARIABLE: может использоваться на локальных переменных. ElementType.ANNOTATION_TYPE: может использоваться на других аннотациях. ElementType.PACKAGE: может использоваться на пакетах.

Пример:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnnotation {
    // Аннотация может использоваться на классах, интерфейсах и методах
}

Эти две аннотации (@Retention и @Target) помогают определить "контракт" пользовательской аннотации - когда и где она будет доступна и использоваться. Они являются важной частью создания собственных аннотаций в Java.


в классе BotCommonCommands используются аннотации в проекте https://gitlab.com/synergy9980417/razdel2/project3_tel_bot


пример использования анотации чтобы выполнять методы которые в ней содержатся с помощью invoke

package org.example;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Scanner;

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {


    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        //TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text
        // to see how IntelliJ IDEA suggests fixing it.
    Commands commands = new Commands();

        for (Method method : commands.getClass().getDeclaredMethods()){
            // таким образом здесь мы получим только те методы которые с нашей анотации, т.е. метода qwerty уже не попадёт сюда
            if (method.isAnnotationPresent(MyCommand.class)){
                MyCommand myCommand = method.getAnnotation(MyCommand.class);
                if (myCommand.showInHelp()){
                    System.out.println(myCommand.name());
                }
            }
        }

        System.out.println("введите метод который нужно выполнить");
        Scanner scanner = new Scanner(System.in);
        final String myCommand = scanner.nextLine();
        for (Method method: commands.getClass().getDeclaredMethods()){
            if (method.isAnnotationPresent(MyCommand.class)){
                MyCommand command = method.getAnnotation(MyCommand.class);
                if (command.name().equals(myCommand)){
                    method.invoke(commands,"opaopa");
                }
            }
        }
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@interface MyCommand {
    String name();
    boolean showInHelp();
}



class Commands{
    @MyCommand(name="privet", showInHelp = true)
    public void privet(String str){
        System.out.println("привет, человек "+str);
    }
    @MyCommand(name="bay", showInHelp = true)
    public void bay(String str){
        System.out.println("пока, человек");
    }
    @MyCommand(name="stop", showInHelp = false)
    void stop(String str){
        System.out.println("it is stop");
    }
void qwerty(){}
}

короткие примеры: https://gitlab.com/synergy9980417/razdel2/4_1-2 https://gitlab.com/synergy9980417/razdel2/4_3