← Назад к вопросам

Как создать аннотацию, применимую только на уровне классов?

2.0 Middle🔥 201 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как создать аннотацию, применимую только на уровне классов?

Использование @Target(ElementType.TYPE)

Для создания аннотации, которую можно применять только на уровне классов, используется аннотация @Target с параметром ElementType.TYPE.

Пример реализации

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassOnly {
    String value() default "";
    int version() default 1;
}

Применение аннотации

@ClassOnly("My Service")
public class MyService {
    // Содержимое класса
}

@ClassOnly
interface MyInterface {
    void doSomething();
}

Элементы аннотации

@Target — определяет, где можно использовать аннотацию:

  • ElementType.TYPE — классы, интерфейсы, enum, записи (records)
  • ElementType.METHOD — методы
  • ElementType.FIELD — поля
  • ElementType.PARAMETER — параметры
  • ElementType.LOCAL_VARIABLE — локальные переменные
  • ElementType.CONSTRUCTOR — конструкторы
  • ElementType.ANNOTATION_TYPE — сами аннотации

@Retention — определяет время жизни аннотации:

  • RetentionPolicy.SOURCE — удаляется компилятором
  • RetentionPolicy.CLASS — доступна в bytecode, но не в runtime
  • RetentionPolicy.RUNTIME — доступна во время выполнения

Правильное использование и ошибки

// ✅ Правильно
@ClassOnly
public class ValidClass {
}

// ❌ Ошибка компиляции
@ClassOnly
public class InvalidExample {
    @ClassOnly  // Ошибка! Нельзя применять на методах
    public void method() {
    }
    
    @ClassOnly  // Ошибка! Нельзя применять на полях
    private String field;
}

Обработка аннотации в runtime

import java.lang.reflect.Field;

public class AnnotationProcessor {
    public static void processClass(Class<?> clazz) {
        if (clazz.isAnnotationPresent(ClassOnly.class)) {
            ClassOnly annotation = clazz.getAnnotation(ClassOnly.class);
            System.out.println("Аннотация найдена: " + annotation.value());
            System.out.println("Версия: " + annotation.version());
        }
    }
}

Практический пример: пользовательская аннотация для конфигурации

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Service {
    String name() default "";
    boolean singleton() default true;
}

@Service(name = "userService", singleton = true)
public class UserService {
    public void createUser(String name) {
        System.out.println("User created: " + name);
    }
}

Ключевые моменты

  • @Target(ElementType.TYPE) ограничивает применение аннотации только классами, интерфейсами и enum
  • Попытка использовать такую аннотацию на методах или полях приведёт к ошибке компиляции
  • @Retention необходимо указывать для обработки аннотаций в runtime
  • Аннотации повышают читаемость кода и позволяют выполнять метапрограммирование
  • Широко используются в Spring (@Service, @Component), Hibernate (@Entity), JUnit (@Test)