Jump to content

Java-аннотация

(Перенаправлено с @FunctionalInterface )

В языке программирования Java аннотация представляет собой форму синтаксических метаданных , которые можно добавлять в исходный код Java . [1] Классы , методы , переменные , параметры и пакеты Java могут быть аннотированы. Как и теги Javadoc , аннотации Java можно читать из исходных файлов. В отличие от тегов Javadoc , аннотации Java также можно встраивать и читать из файлов классов Java, созданных компилятором Java . сохранять аннотации Это позволяет виртуальной машине Java во время выполнения и читать их посредством отражения . [2] В Java можно создавать метааннотации из существующих. [3]

Платформа Java имеет различные механизмы специальных аннотаций, например transient модификатор, или @Deprecated тег javadoc. Запрос на спецификацию Java JSR-175 представил возможность аннотаций общего назначения (также известных как метаданные ) в процессе сообщества Java в 2002 году; он получил одобрение в сентябре 2004 года. [4]

Аннотации стали доступны в самом языке, начиная с версии 1.5 Java Development Kit (JDK). apt инструмент предоставил временный интерфейс для обработки аннотаций во время компиляции в JDK версии 1.5; он был интегрирован в компилятор javac JSR-269 формализовал это, и в версии 1.6 .

Встроенные аннотации

[ редактировать ]

Java определяет набор аннотаций, встроенных в язык. Из семи стандартных аннотаций три являются частью java.lang , а остальные четыре импортированы из java.lang.annotation. [5] [6]

Аннотации, применяемые к коду Java:

Аннотации, применяемые к другим аннотациям (также известные как «метааннотации»):

  • @Retention — Указывает, как сохраняется отмеченная аннотация: только в коде, скомпилирована в класс или доступна во время выполнения посредством отражения.
  • @Documented - Отмечает другую аннотацию для включения в документацию.
  • @Target — Отмечает другую аннотацию, чтобы ограничить тип элементов Java, к которым может применяться эта аннотация.
  • @Inherited — Отмечает другую аннотацию, которая будет унаследована подклассами аннотированного класса (по умолчанию аннотации не наследуются подклассами).

Начиная с Java 7, в язык были добавлены три дополнительные аннотации.

  • @SafeVarargs — Подавление предупреждений для всех вызывающих методов или конструкторов с помощью параметра generics varargs , начиная с Java 7.
  • @FunctionalInterface — Указывает, что объявление типа предназначено для использования в качестве функционального интерфейса , начиная с Java 8.
  • @Repeatable — Указывает, что аннотация может применяться более одного раза к одному и тому же объявлению, начиная с Java 8.

Встроенные аннотации

[ редактировать ]

Этот пример демонстрирует использование @Override аннотация. Он дает указание компилятору проверить родительские классы на наличие соответствующих методов. В этом случае генерируется ошибка, поскольку gettype() метод класса Cat фактически не переопределяет getType() желательно класса Animal Like из-за несовпадающего регистра . Если @Override аннотации отсутствовали, новый метод имени gettype() будет создан в классе Cat.

public class Animal {
    public void speak() {
    }

    public String getType() {
        return "Generic animal";
    }
}

public class Cat extends Animal {
    @Override
    public void speak() { // This is a good override.
        System.out.println("Meow.");
    }

    @Override
    public String gettype() { // Compile-time error due to typo: should be getType() not gettype().
        return "Cat";
    }
}

Пользовательские аннотации

[ редактировать ]

Объявления типов аннотаций аналогичны обычным объявлениям интерфейсов. Знак (@) предшествует ключевому слову «интерфейс».

  // @Twizzle is an annotation to method toggle().
  @Twizzle
  public void toggle() {
  }

  // Declares the annotation Twizzle.
  public @interface Twizzle {
  }

Аннотации могут включать набор пар ключ-значение, которые моделируются как методы типа аннотации. Каждое объявление метода определяет элемент типа аннотации. Объявления методов не должны иметь никаких параметров или предложения throws. Типы возвращаемых значений ограничены примитивами , строками , классами, перечислениями , аннотациями и массивами предыдущих типов. Методы могут иметь значения по умолчанию .

  // Same as: @Edible(value = true)
  @Edible(true)
  Item item = new Carrot();

  public @interface Edible {
      boolean value() default false;
  }

  @Author(first = "Oompah", last = "Loompah")
  Book book = new Book();

  public @interface Author {
      String first();
      String last();
  }

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

  @Retention(RetentionPolicy.RUNTIME) // Make this annotation accessible at runtime via reflection.
  @Target({ElementType.METHOD})       // This annotation can only be applied to class methods.
  public @interface Tweezable {
  }

Компилятор резервирует набор специальных аннотаций (в том числе @Deprecated, @Override и @SuppressWarnings) для синтаксических целей.

Аннотации часто используются платформами как способ удобного применения поведения к определяемым пользователем классам и методам, которые в противном случае должны быть объявлены во внешнем источнике (например, в файле конфигурации XML) или программно (с помощью вызовов API). Ниже приведен, например, аннотированный класс данных JPA :

@Entity                                             // Declares this an entity bean
@Table(name = "people")                             // Maps the bean to SQL table "people"
public class Person implements Serializable {
    @Id                                             // Map this to the primary key column.
    @GeneratedValue(strategy = GenerationType.AUTO) // Database will generate new primary keys, not us.
    private Integer id;

    @Column(length = 32)                            // Truncate column values to 32 characters.
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Аннотации не являются вызовами методов и сами по себе ничего не делают. Вместо этого объект класса передается реализации JPA во время выполнения , которая затем извлекает аннотации для создания объектно-реляционного сопоставления .

Полный пример приведен ниже:

package com.annotation;

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

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,
         ElementType.CONSTRUCTOR,ElementType.ANNOTATION_TYPE,
         ElementType.PACKAGE,ElementType.FIELD,ElementType.LOCAL_VARIABLE})
@Inherited

public @interface Unfinished {
    public enum Priority { LOW, MEDIUM, HIGH }
    String value();
    String[] changedBy() default "";
    String[] lastChangedBy() default "";
    Priority priority() default Priority.MEDIUM;
    String createdBy() default "James Gosling";
    String lastChanged() default "2011-07-08";
}
package com.annotation;

public @interface UnderConstruction {
    String owner() default "Patrick Naughton";
    String value() default "Object is Under Construction.";
    String createdBy() default "Mike Sheridan";
    String lastChanged() default "2011-07-08";
}
package com.validators;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import com.annotation.UnderConstruction;
import com.annotation.Unfinished;
import com.annotation.Unfinished.Priority;
import com.util.Util;

@UnderConstruction(owner="Jon Doe")
public class DateValidator implements Validator {
	
    public void validate(FacesContext context, UIComponent component, Object value)
        throws ValidatorException {
        String date = (String) value;
        String errorLabel = "Please enter a valid date.";
        if (!component.getAttributes().isEmpty()) {
            errorLabel = (String) component.getAttributes().get("errordisplayval");
        }

        if (!Util.validateAGivenDate(date)) {
            @Unfinished(changedBy = "Steve",
                value = "whether to add message to context or not, confirm",
                priority = Priority.HIGH
            )
            FacesMessage message = new FacesMessage();
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            message.setSummary(errorLabel);
            message.setDetail(errorLabel);
            throw new ValidatorException(message);
        }
    }
}

Обработка

[ редактировать ]

Когда исходный код Java компилируется, аннотации могут обрабатываться подключаемыми модулями компилятора, называемыми процессорами аннотаций. Процессоры могут создавать информационные сообщения или создавать дополнительные исходные файлы или ресурсы Java, которые, в свою очередь, могут быть скомпилированы и обработаны. Однако процессоры аннотаций не могут изменять сам аннотированный код. (Модификации кода могут быть реализованы с использованием методов, выходящих за рамки спецификации языка Java.) Компилятор Java условно сохраняет метаданные аннотации в файлах классов, если аннотация имеет RetentionPolicy из CLASS или RUNTIME. Позже JVM или другие программы могут искать метаданные, чтобы определить, как взаимодействовать с элементами программы или изменить их поведение.

Помимо обработки аннотации с помощью процессора аннотаций, Java-программист может написать собственный код, использующий отражение для обработки аннотации. Java SE 5 поддерживает новый интерфейс, определенный в java.lang.reflect упаковка. Этот пакет содержит интерфейс под названием AnnotatedElement который реализуется классами отражения Java, включая Class, Constructor, Field, Method, и Package. Реализации этого интерфейса используются для представления аннотированного элемента программы, работающей в данный момент на виртуальной машине Java. Этот интерфейс позволяет рефлективно читать аннотации.

The AnnotatedElement интерфейс обеспечивает доступ к аннотациям, имеющим RUNTIME удержание. Этот доступ обеспечивается getAnnotation, getAnnotations, и isAnnotationPresent методы. Поскольку типы аннотаций компилируются и сохраняются в файлах байт-кода, как и классы, аннотации, возвращаемые этими методами, можно запрашивать так же, как и любой обычный объект Java. Полный пример обработки аннотации приведен ниже:

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

// This is the annotation to be processed
// Default for Target is all Java Elements
// Change retention policy to RUNTIME (default is CLASS)
@Retention(RetentionPolicy.RUNTIME)
public @interface TypeHeader {
    // Default value specified for developer attribute
    String developer() default "Unknown";
    String lastModified();
    String [] teamMembers();
    int meaningOfLife();
}
// This is the annotation being applied to a class
@TypeHeader(developer = "Bob Bee",
    lastModified = "2013-02-12",
    teamMembers = { "Ann", "Dan", "Fran" },
    meaningOfLife = 42)

public class SetCustomAnnotation {
    // Class contents go here
}
// This is the example code that processes the annotation
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;

public class UseCustomAnnotation {
    public static void main(String [] args) {
        Class<SetCustomAnnotation> classObject = SetCustomAnnotation.class;
        readAnnotation(classObject);
    }

    static void readAnnotation(AnnotatedElement element) {
        try {
            System.out.println("Annotation element values: \n");
            if (element.isAnnotationPresent(TypeHeader.class)) {
                // getAnnotation returns Annotation type
                Annotation singleAnnotation = 
                        element.getAnnotation(TypeHeader.class);
                TypeHeader header = (TypeHeader) singleAnnotation;

                System.out.println("Developer: " + header.developer());
                System.out.println("Last Modified: " + header.lastModified());

                // teamMembers returned as String []
                System.out.print("Team members: ");
                for (String member : header.teamMembers())
                    System.out.print(member + ", ");
                System.out.print("\n");

                System.out.println("Meaning of Life: "+ header.meaningOfLife());
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

См. также

[ редактировать ]
  1. ^ «Аннотации» . Сан Микросистемс . Архивировано из оригинала 25 сентября 2011 г. Проверено 30 сентября 2011 г. .
  2. ^ Сан Микросистемы (2005). Спецификация языка Java(TM) (3-е изд.). Прентис Холл . ISBN  0-321-24678-0 . .
  3. ^ Дэйр Обасанджо (2007). «СРАВНЕНИЕ ЯЗЫКА ПРОГРАММИРОВАНИЯ C# MICROSOFT С ЯЗЫКОМ ПРОГРАММИРОВАНИЯ JAVA SUN MICROSYSTEMS: Аннотации метаданных» . Дэйр Обасанджо. Архивировано из оригинала 19 сентября 2012 г. Проверено 20 сентября 2012 г.
  4. ^ Трус, Дэнни (2 ноября 2006 г.). «JSR 175: средство метаданных для языка программирования JavaTM» . Процесс сообщества Java . Проверено 5 марта 2008 г.
  5. ^ «Предопределенные типы аннотаций» . Корпорация Оракл . Проверено 17 декабря 2016 г.
  6. ^ «Встроенные аннотации: стандартные аннотации» . Проверено 17 декабря 2016 г.
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 823748cd0c499189915c01a51cfe2ba5__1719579840
URL1:https://arc.ask3.ru/arc/aa/82/a5/823748cd0c499189915c01a51cfe2ba5.html
Заголовок, (Title) документа по адресу, URL1:
Java annotation - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)