English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Neste tutorial, vamos aprender diferentes tipos de anotações Java com exemplos.
As anotações Java são metadados de nosso código-fonte (dados sobre dados). A Java SE fornece várias anotações pré-definidas. Além disso, podemos criar anotações personalizadas conforme necessário.
Se você não sabe o que é anotação, acesseAnotações JavaTutorial.
Essas anotações podem ser classificadas como:
1. Anotações pré-definidas
@Deprecated
@Override
@SuppressWarnings
@SafeVarargs
@FunctionalInterface
2. Anotações personalizadas
3. Anotações meta
@Retention
@Documented
@Target
@Inherited
@Repeatable
A anotação @Descontinuado é uma anotação de sinalização que indica que o elemento (classe, método, campo, etc.) está desatualizado e foi substituído por um elemento atualizado.
Sua sintaxe é:
@Deprecated accessModifier returnType descontinuadoMethodName() { ... }
Quando o programa usa elementos declarados como descontinuados, o compilador gera avisos.
Usamos a marca @descontinuado do Javadoc para registrar elementos descontinuados.
/** * @descontinuado * Porque foi descontinuado */ @Deprecated accessModifier returnType descontinuadoMethodName() { ... }
class Main { /** * @descontinuado * Este método foi descontinuado e substituído por newMethod()} */ @Deprecated public static void deprecatedMethod() { System.out.println("Deprecated method"); } public static void main(String args[]) { deprecatedMethod(); } }
Resultados de saída
Deprecated method
A anotação @Override especifica que o método da subclasse deve sobrescrever o método da superclasse com o mesmo nome de método, tipo de retorno e lista de parâmetros.
A anotação @Override não é necessária ao sobrescrever métodos. No entanto, se for usada, o compilador fornecerá um erro se houver um erro (por exemplo, tipo de parâmetro incorreto) ao sobrescrever o método.
class Animal { //Método rewritten public void display(){ System.out.println("Eu sou um animal"); } } class Dog extends Animal { //Método rewritten @Override public void display(){ System.out.println("Eu sou um cachorro"); } public void printMessage(){ display(); } } class Main { public static void main(String[] args) { Dog dog1 = new Dog(); dog1.printMessage(); } }
Resultados de saída
Eu sou um cachorro
Neste exemplo, através da criação de um objeto da classe Dog chamado dog1Podemos chamar seu método printMessage(), e então esse método executa a instrução display().
Como o método display() foi definido em dois classes, o método display() da subclasse Dog substitui o método display() da superclasse Animal. Portanto, o método da subclasse é chamado.
Como o nome sugere, a anotação @SuppressWarnings indica ao compilador que deve proibir a geração de avisos durante a execução do programa.
Podemos especificar o tipo de aviso a ser removido. Os avisos que podem ser proibidos são específicos do compilador, mas os avisos são divididos em dois tipos:Descontinuado E Não verificado.
Para proibir a exibição de avisos de categorias específicas, deliberadamente usamos:
@SuppressWarnings("warningCategory")
Por exemplo,
@SuppressWarnings("deprecated")
Para proibir a exibição de vários tipos de avisos, deliberadamente usamos:
@SuppressWarnings("warningCategory"1", "warningCategory2"})
Por exemplo,
@SuppressWarnings({"deprecated", "unchecked"})
Quando usamos elementos não recomendados, a categoria deprecated indica ao compilador que deve proibir a exibição de avisos.
当我们使用原始类型时,unchecked类别指示编译器禁止显示警告。
并且,未定义的警告将被忽略。例如,
@SuppressWarnings("someundefinedwarning")
class Main { @Deprecated public static void deprecatedMethod() { System.out.println("Deprecated method"); } @SuppressWarnings("deprecated") public static void main(String args[]) { Main depObj = new Main(); depObj. deprecatedMethod(); } }
Resultados de saída
Deprecated method
在这里,deprecatedMethod()已被标记为已弃用,使用时会发出编译器警告。通过使用@SuppressWarnings("deprecated")注解,我们可以避免编译器警告。
@SafeVarargs注解断言,带注解的方法或构造不执行它的可变参数不安全的操作(可变的参数数)。
我们只能在不能被重写的方法或构造函数上使用此注解。这是因为重写它们的方法可能会执行不安全的操作。
在Java 9之前,我们只能在final或static方法上使用此注解,因为它们不能被重写。现在,我们也可以将此注解用于私有方法。
import java.util.*; class Main { private void displayList(List<String>... lists) { for (List<String> list : lists) { System.out.println(list); } } public static void main(String args[]) { Main obj = new Main(); List<String> universityList = Arrays.asList("Tribhuvan University", "Kathmandu University"); obj.displayList(universityList); List<String> programmingLanguages = Arrays.asList("Java", "C"); obj.displayList(universityList, programmingLanguages); } }
Itens de aviso
Segurança de tipo: Poluição de heap via parâmetros de lista varargs Segurança de tipo: Um array genérico de List<String> é criado para um varargs parâmetro
Resultados de saída
Nota: Main.java usa operações não verificadas ou inseguras. [Universidade Tribhuvan, Universidade de Kathmandu] [Universidade Tribhuvan, Universidade de Kathmandu] [Java, C]
Aqui, List ... list especifica o tipo como List de argumentos variáveis. Isso significa que o método displayList() pode ter zero ou mais argumentos.
O programa acima compila sem erros, mas emite um aviso ao não usar a anotação @SafeVarargs.
Quando usamos a anotação @SafeVarargs no exemplo acima,
@SafeVarargs private void displayList(List<String>... lists) { ... }
Obtemos a mesma saída, mas sem nenhum aviso. Quando usamos essa anotação, avisos não verificados também são removidos.
Java 8Primeiro, introduzimos essa anotação @FunctionalInterface. Essa anotação indica que o tipo declarado com ela é uma interface funcional. Uma interface funcional pode ter apenas um método abstrato.
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); //Isso é um método abstrato }
Se adicionarmos outro método abstrato, então
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); // Isso é um método abstrato public void secondMethod(); //Isso gerará um erro de compilação }
Agora, quando executarmos o programa, receberemos o seguinte aviso:
Anotação @FunctionalInterface inesperada @FunctionalInterface ^ MyFuncInterface não é uma interface funcional múltiplos não-overriding métodos abstratos encontrados na interface MyFuncInterface
O uso da anotação @FunctionalInterface não é obrigatório. O compilador considera qualquer interface que atenda à definição da interface funcional como uma interface funcional.
O propósito da anotação @FunctionalInterface é garantir que a interface funcional tenha apenas um método abstrato.
Mas, pode ter qualquer quantidade de métodos padrão e estáticos, porque eles têm implementação.
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); //Este é um método abstrato default void secondMethod() { ... } default void thirdMethod() { ... } }
Também podemos criar nossas próprias anotações personalizadas.
Sua sintaxe é:
[Especificador de Acesso] @interface<NomeDeAnotacao> { DataType <MethodName>() [valor padrão]; }
Esta é a informação que você precisa saber sobre anotações personalizadas:
As anotações podem ser criadas usando @interface seguido do nome da anotação.
As anotações podem ter elementos que parecem métodos, mas não têm implementação.
O valor padrão é opcional. Os parâmetros não podem ser valores nulos.
O tipo de retorno do método pode ser primitivo, enum, string, nome de classe ou array desses tipos.
@interface MyCustomAnnotation { String value() default "default value"; } class Main { @MyCustomAnnotation(value = "w3codebox) public void method1() { System.out.println("Método de teste1"); } public static void main(String[] args) throws Exception { Main obj = new Main(); obj.method1(); } }
Resultados de saída
Método de teste1
Anotações meta são anotações aplicadas a outras anotações.
A anotação @Retention especifica o nível mais alto de disponibilidade da anotação.
Sua sintaxe é:
@Retention(RetentionPolicy)
Existem três tipos:
RetentionPolicy.SOURCE - A notação de anotação está disponível apenas no nível da fonte e é ignorada pelo compilador.
RetentionPolicy.CLASS - A anotação está disponível para o compilador no tempo de compilação, mas o Java Virtual Machine (JVM) ignorará ela.
RetentionPolicy.RUNTIME - A anotação pode ser usada no JVM.
Por exemplo,
@Retention(RetentionPolicy.RUNTIME) public @interface MyCustomAnnotation{ ... }
Por padrão, as anotações personalizadas não são incluídas no documento oficial do Java. Para incluir a anotação no documento Javadoc, use a anotação @Documented.
Por exemplo,
@Documented public @interface MyCustomAnnotation{ ... }
Podemos usar a anotação @Target para limitar a aplicação da anotação a um objetivo específico.
Sua sintaxe é:
@Target(ElementType)
ElementType pode ser um dos seguintes tipos:
Tipo de elemento | Target |
---|---|
ElementType.ANNOTATION_TYPE | Tipo de anotação |
ElementType.CONSTRUCTOR | Construtor |
ElementType.FIELD | Campo |
ElementType.LOCAL_VARIABLE | Variável local |
ElementType.METHOD | Método |
ElementType.PACKAGE | Pacote |
ElementType.PARAMETER | Parâmetros |
ElementType.TYPE | Usado para descrever declarações de classe, interface (incluindo tipos de anotação) ou enum |
Por exemplo,
@Target(ElementType.METHOD) public @interface MyCustomAnnotation{ ... }
Neste exemplo, limitamos o uso desta anotação apenas aos métodos.
Atenção:Se o tipo de destino não for definido, a anotação pode ser usada para qualquer elemento.
Por padrão, o tipo de anotação não pode ser herdado da superclasse. No entanto, se necessário, para herdar a anotação da superclasse para a subclasse, você pode usar a anotação @Inherited.
Sua sintaxe é:
@Inherited
Por exemplo,
@Inherited public @interface MyCustomAnnotation { ... } @MyCustomAnnotation public class ParentClass{ ... } public class ChildClass extends ParentClass { ... }
A anotação com a marca @Repeatable pode ser aplicada várias vezes ao mesmo declaração.
@Repeatable(Universities.class) public @interface University { String name(); }
O valor definido na anotação @Repeatable é uma anotação contêiner. As anotações contêiner têm o valor do array de anotações reiteráveis (value). Aqui, Universities é o contêiner que contém os tipos de anotação.
public @interface Universities { University[] value(); }
Agora, a anotação @University pode ser usada várias vezes na mesma declaração.
@University(name = "TU") @University(name = "KU") private String uniName;
Se precisar recuperar dados de anotação, você pode usarReflexão.
Para recuperar valores de anotações, usamos os métodos definidos na API de reflexão getAnnotationsByType() ou getAnnotations().