English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Tutorial Básico de Java

Controle de fluxo Java

Java Array

Java Orientação a Objetos (I)

Java Orientação a Objetos (II)

Java Orientação a Objetos (III)

Tratamento de Exceções Java

Java Lista (List)

Java Fila (Fila)

Java Conjunto Map

Java Conjunto Set

Java Entrada e Saída (I/O)

Reader Java/Writer

Outros tópicos Java

Tipos de anotação Java

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

Tipos de anotações pré-definidas

1. @Descontinuado

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() { ... }

Exemplo1:@Descontinuado exemplo de anotação

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

2. @Override

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.

Exemplo2Exemplo de anotação @Override

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.

3. @SuppressWarnings

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")

Exemplo3:@SuppressWarnings 注解示例

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")注解,我们可以避免编译器警告。

4. @SafeVarargs

@SafeVarargs注解断言,带注解的方法或构造不执行它的可变参数不安全的操作(可变的参数数)。

我们只能在不能被重写的方法或构造函数上使用此注解。这是因为重写它们的方法可能会执行不安全的操作。

在Java 9之前,我们只能在final或static方法上使用此注解,因为它们不能被重写。现在,我们也可以将此注解用于私有方法。

Exemplo4:@SafeVarargs注解示例

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.

5. @FunctionalInterface

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.

Exemplo5Exemplo de anotação @FunctionalInterface

@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() { ... } 
}

Anotações personalizadas

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.

Exemplo6:Exemplo de anotação personalizada

@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

Anotações meta são anotações aplicadas a outras anotações.

1. @Retention

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{ ... }

2. @Documented

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{ ... }

3. @Target

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 elementoTarget
ElementType.ANNOTATION_TYPETipo de anotação
ElementType.CONSTRUCTORConstrutor
ElementType.FIELDCampo
ElementType.LOCAL_VARIABLEVariável local
ElementType.METHODMétodo
ElementType.PACKAGEPacote
ElementType.PARAMETERParâmetros
ElementType.TYPEUsado 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.

4. @Inherited

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 { ... }

5. @Repeatable

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().