viernes, 6 de abril de 2012

Anotaciones en Java

votar
   Esta entrada va a ser básicamente teórica, porque hoy vamos a hablar de las anotaciones en Java.
   Las anotaciones son una especie de comentarios o metadatos que puedes introducir en tu código, pero que no son en realidad parte del programa. Puedes elegir que sean procesadas durante la compilación o bien durante la ejecución, a través del API de Reflection. La regla de oro a seguir es que el programa debe funcionar igual tanto si le añades como si le quitas las anotaciones.

   Las anotaciones se escriben siempre antes del elemento al que anotan, por ejemplo:

      @MiAnotación(nombre = "unNombre", valor = "unValor")
      public class MiClase{ }

   Si sólo tiene un parámetro, puede escribirse así: 

      @MiAnotación("unNombre")

   La forma de definir una anotación es como la de una interfaz con el signo @ delante:

      public @ interface MiAnotación{
         String nombre(); //miembros declarados como métodos sin argumentos
         String valor();
      }

   Una vez que has definido una anotación, ya puedes usarla en tu código. Por ejemplo, puedes crear una anotación para especificar los autores y versiones de un determinado programa:

      
@interface Creación{
      String autores();
      String fecha();
      int versión() default 1;
}

  Y ahora, al inicio del programa:

@Creación(  //con paréntesis
          autores = "Java Para Nulos", //parámentros separados por comas
          fecha = "05/04/2012",
          versión = 3 //si no se indicase nada, se aplicaría el valor por defecto
         )

  Hay algunas anotaciones ya predefinidas en el lenguaje y que resultan útiles a la hora de compilar:


     @Override - informa al compilador que el método al que anota está sobreescribiendo un método de la superclase. Si por algún motivo no sobreescribimos bien el método, el compilador genera un error indicando dónde está el fallo.


    @Deprecated - un elemento marcado con esta anotación indica que está en desuso, bien porque es peligroso, bien porque hay otra alternativa mejor. Un elemento así debería ser también comentado utilizando la etiqueta @deprecated(con minúscula). El compilador genera un aviso cuando se utiliza un elemento marcado @Deprecated.


    @SuppressWarnings - indica al compilador que elimine dos tipos de advertencias que generaría de otro modo: 

  • deprecation: para que no genere una advertencia cuando se utiliza un elemento marcado como @Deprecated.
  • unchecked:  cuando se utiliza código creado antes de la aparición de los genéricos ( y no hablamos de medicamentos aquí).
   La forma de escribir esta anotación es la siguiente:
      @SuppressWarnings("deprecation")
      o en caso de que sean los dos tipos:
      @SuppressWarnings({"unchecked", "deprecation"})


   La anotación @SuppressWarnings debe utilizarse con precaución y aplicándola al mínimo elemento posible. Es decir, si no quieres que el compilador genere una advertencia por utilizar un método en desuso, marca ese método, y no toda la clase, porque podrías eliminar otras advertencias importantes.


   Esto nos lleva a las Meta-Anotaciones, o anotaciones de anotaciones. Por ejemplo, si marcamos una anotación con @Target(ElementType.METHOD) estamos indicando que dicha anotación sólo se aplica al método. ElementType es un enum, y los demás valores que tiene son:

  • FIELD
  • PARAMETER
  • CONSTRUCTOR
  • LOCAL_VARIABLE
  • ANNOTATION_TYPE
  • PACKAGE
   Además de @Target, tenemos las siguientes meta-anotaciones:


   @Retention - que indica hasta dónde se mantienen las anotaciones. Hay tres modos posibles:

  • Retention(RetentionPolicy.SOURCE), la anotación sólo se aplica al código fuente, siendo ignorada por el compilador y la JVM.
  • Retention(RetentionPolicy.CLASS), el compilador puede ver la anotación y actuar en consecuencia, pero es ignorada por la JVM.
  • Retention(RetentionPolicy.RUNTIME), la JVM puede ver la anotación y utilizarla en tiempo de ejecución con Reflection.

   @Documented - indica que la anotación deberá ser tenida en cuenta por la herramienta javadoc o similares. Estas anotaciones pasan a ser parte del API público de los elementos anotados. Es un tipo de anotación "marcador", es decir, no tiene miembros.



   @Inherited - indica que una anotación es automáticamente heredada. Esta meta-anotación sólo tiene efecto en anotaciones de clase, y sólo se hereda de superclases, no de interfaces.


   Cualquier duda o comentario que queráis hacer, ya sabéis dónde estamos ; )

2 comentarios:

  1. Gracias por la explicación ! tenia muchas dudas sobre las anotaciones y eso que las ocupaba frecuente

    ResponderEliminar