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). O 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, acesseJava 注解Tutorial.
Essas anotações podem ser classificadas como:
1. Anotações pré-definidas
@Deprecated
@Override
@SuppressWarnings
@SafeVarargs
@FunctionalInterface
2. Anotaciones personalizadas
3. Anotaciones meta
@Retention
@Documented
@Target
@Inherited
@Repeatable
@Desatualizado é uma anotação de marca que indica que o elemento (classe, método, campo, etc.) está desatualizado e foi substituído por um elemento atualizado.
su sintaxis es:
@Deprecated accessModifier returnType desatualizadoMethodName() { ... }
Quando o programa usa elementos declarados como descontinuados, o compilador gera avisos.
Usamos a marca @desatualizado do Javadoc para registrar elementos descontinuados.
/** * @desatualizado * Porque foi descontinuado */ @Deprecated accessModifier returnType desatualizadoMethodName() { ... }
class Main { /** * @desatualizado * Este método se ha descontinuado y ha sido reemplazado por newMethod() */ @Deprecated public static void deprecatedMethod() { System.out.println("弃用方法"); } public static void main(String args[]) { deprecatedMethod(); } }
Resultados de salida
弃用方法
La anotación @Override especifica que el método de la subclase debe sobrescribir el método de la superclase con el mismo nombre de método, tipo de retorno y lista de parámetros.
@Override no es obligatorio al sobrescribir métodos. Sin embargo, si se utiliza, si hay un error (por ejemplo, tipo de parámetro incorrecto) en la sobrescripción del método, el compilador emitirá un error.
class Animal { //Método sobreescrito public void display(){ System.out.println("Soy un animal"); } } class Dog extends Animal { //Método sobreescrito @Override public void display(){ System.out.println("Soy un perro"); } public void printMessage(){ display(); } } class Main { public static void main(String[] args) { Dog dog1 = new Dog(); dog1.printMessage(); } }
Resultados de salida
Soy un perro
En este ejemplo, creando el objeto de la clase Dog llamado dog1,podemos llamar a su método printMessage(), luego ese método ejecuta la sentencia display().
Dado que display() ya se ha definido en dos clases, el método display() de la subclase Dog sobrescribe el método display() de la superclase Animal. Por lo tanto, se llama al método de la subclase.
Como su nombre indica, la anotación @SuppressWarnings indica que el compilador debe prohibir las advertencias generadas durante la ejecución del programa.
Podemos especificar el tipo de advertencia que deseamos deshabilitar. Las advertencias que se pueden prohibir son específicas del compilador, pero las advertencias se dividen en dos categorías:Descontinuado Y No revisado。
Para prohibir la visualización de advertencias de categorías específicas, utilizamos intencionalmente:
@SuppressWarnings("warningCategory")
Por ejemplo,
@SuppressWarnings("deprecated")
Para prohibir la visualización de múltiples categorías de advertencias, utilizamos intencionalmente:
@SuppressWarnings("warningCategory1", "warningCategory2"})
Por ejemplo,
@SuppressWarnings({"deprecated", "unchecked"})
Cuando utilizamos elementos no recomendados, la categoría deprecated indica que el compilador debe prohibir la visualización de advertencias.
当我们使用原始类型时,unchecked类别指示编译器禁止显示警告。
并且,未定义的警告将被忽略。例如,
@SuppressWarnings("someundefinedwarning")
class Main { @Deprecated public static void deprecatedMethod() { System.out.println("弃用方法"); } @SuppressWarnings("deprecated") public static void main(String args[]) { Main depObj = new Main(); depObj. deprecatedMethod(); } }
Resultados de salida
弃用方法
在这里,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); } }
Advertencias
Seguridad de tipo: Contaminación de pila potencial a través de listas de parámetros variables Seguridad de tipo: Se crea un array genérico de List<String> para un parámetro variables parámetro
Resultados de salida
Nota: Main.java utiliza operaciones no verificadas o inseguras. [Tribhuvan University, Kathmandu University] [Tribhuvan University, Kathmandu University] [Java, C]
Aquí, List ... list especifica el tipo como List de parámetros variables. Esto significa que el método displayList() puede tener cero o más parámetros.
El programa anterior se compila sin errores, pero genera una advertencia cuando no se usa la anotación @SafeVarargs.
Al usar la anotación @SafeVarargs en el ejemplo anterior,
@SafeVarargs private void displayList(List<String>... lists) { ... }
Obtenemos la misma salida, pero sin advertencias. Al usar esta anotación, también se eliminan las advertencias no verificadas.
Java 8Primero se introduce esta anotación @FunctionalInterface. Esta anotación indica que el tipo declarado con ella es una interfaz funcional. Una interfaz funcional puede tener solo un método abstracto.
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); //Esto es un método abstracto }
Si añadimos otro método abstracto, entonces
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); // Esto es un método abstracto public void secondMethod(); //Esto generará un error de compilación }
Ahora, cuando ejecutamos el programa, recibiremos el siguiente aviso:
Anotación @FunctionalInterface inesperada @FunctionalInterface ^ MyFuncInterface no es una interfaz funcional múltiples no-sobreescritura de métodos abstractos encontrados en la interfaz MyFuncInterface
El uso de la anotación @FunctionalInterface no es obligatorio. El compilador considerará cualquier interfaz que cumpla con la definición del interfaz funcional como interfaz funcional.
El propósito de usar esta anotación es asegurar que el interfaz funcional tenga solo un método abstracto.
Pero, puede tener cualquier cantidad de métodos de defecto y métodos estáticos, ya que todos tienen implementación.
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); //Esto es un método abstracto default void secondMethod() { ... } default void thirdMethod() { ... } }
También podemos crear nuestras propias anotaciones personalizadas.
su sintaxis es:
[Specificador de acceso] @interface<NombreDeAnotación> { DataType <MethodName>() [valor por defecto]; }
Esta es la información que necesita saber sobre las anotaciones personalizadas:
Las anotaciones se pueden crear utilizando @interface seguido del nombre de la anotación.
Las anotaciones pueden tener elementos que parecen métodos, pero no tienen implementación.
El valor por defecto es opcional. Los parámetros no pueden ser valores nulos.
El tipo de retorno del método puede ser primitivo, enumeración, cadena, nombre de clase o un array de estos tipos.
@interface MyCustomAnnotation { String value() default "default value"; } class Main { @MyCustomAnnotation(value = "w3codebox) public void method1() { System.out.println("Método de prueba1"); } public static void main(String[] args) throws Exception { Main obj = new Main(); obj.method1(); } }
Resultados de salida
Método de prueba1
Las anotaciones meta son anotaciones aplicadas a otras anotaciones.
La anotación @Retention especifica el nivel más alto de disponibilidad de esta anotación.
su sintaxis es:
@Retention(RetentionPolicy)
Hay tres tipos:
RetentionPolicy.SOURCE - La anotación solo está disponible en el nivel de fuente y es ignorada por el compilador.
RetentionPolicy.CLASS - La anotación está disponible para el compilador en tiempo de compilación, pero el Java Virtual Machine (JVM) la ignorará.
RetentionPolicy.RUNTIME - La anotación se puede usar en el JVM.
Por ejemplo,
@Retention(RetentionPolicy.RUNTIME) public @interface MyCustomAnnotation{ ... }
Por defecto, las anotaciones personalizadas no se incluyen en la documentación oficial de Java. Para incluir la anotación en la documentación Javadoc, utilice la anotación @Documented.
Por ejemplo,
@Documented public @interface MyCustomAnnotation{ ... }
Podemos usar la anotación @Target para limitar la aplicación de la anotación a un objetivo específico.
su sintaxis es:
@Target(ElementType)
ElementType puede tener uno de los siguientes tipos:
Tipo de elemento | Target |
---|---|
ElementType.ANNOTATION_TYPE | Tipo de anotación |
ElementType.CONSTRUCTOR | Constructor |
ElementType.FIELD | Campo |
ElementType.LOCAL_VARIABLE | Variable local |
ElementType.METHOD | Método |
ElementType.PACKAGE | Paquete |
ElementType.PARAMETER | Parámetros |
ElementType.TYPE | Se utiliza para describir declaraciones de clase, interfaz (incluyendo tipos de anotaciones) o enum. |
Por ejemplo,
@Target(ElementType.METHOD) public @interface MyCustomAnnotation{ ... }
En este ejemplo, limitamos el uso de esta anotación solo a los métodos.
Nota:Si no se define el tipo de destino, la anotación se puede aplicar a cualquier elemento.
Por defecto, el tipo de anotación no puede heredarse de la clase superior. Pero, si es necesario heredar la anotación de la clase superior a la subclase, se puede utilizar la anotación @Inherited.
su sintaxis es:
@Inherited
Por ejemplo,
@Inherited public @interface MyCustomAnnotation { ... } @MyCustomAnnotation public class ParentClass{ ... } public class ChildClass extends ParentClass { ... }
Las anotaciones con la marca @Repeatable pueden aplicarse múltiples veces al mismo declarativo.
@Repeatable(Universities.class)} public @interface University { String name(); }
@Repeatable注解中定义的值是容器注解。容器注解具有上述可重复注解数组类型的变量值(value)。在这里,Universities是包含注解类型的。
public @interface Universities { University[] value(); }
现在,@University注解可以在同一声明上多次使用。
@University(name = "TU") @University(name = "KU") private String uniName;
如果需要检索注解数据,可以使用反射。
要检索注解值,我们使用反射API中定义的getAnnotationsByType()或getAnnotations()方法。