2011-10-09 9 views
9

Estoy todavía bastante nuevo en la programación Java y que estaba buscando en un proyecto de código abierto y me encontré con este¿Cómo funcionan las anotaciones de usuario?

public @TileNetworkData int progressPart = 0; 

he visto el uso de @ antes, pero sólo para hacer cosas como @override antes de que un miembro. Para mi sorpresa, mirando hacia arriba la definición que me llevó a código de usuario

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

@Retention(RetentionPolicy.RUNTIME) 
@Inherited 
public @interface TileNetworkData { 

    int staticSize() default -1; 

} 

Lo que está haciendo el código, y lo que es útil para? Parece que está agregando alguna forma de metadatos al campo. ¿Cómo se usa algo como esto?

Haciendo algo de Google Encontré que esto se llama "Anotaciones", pero todo lo relacionado con él se me pasó por la cabeza. Se apreciaría cualquier tipo de ejemplo en el que se usara algo como esto.

Respuesta

5

Annotations se utilizan como "metadatos legibles por máquina": describen los campos, los métodos y las clases que etiquetan de forma que el compilador y el tiempo de ejecución pueden analizar e incluso comprender. Si está familiarizado con .NET's attributes, encontrará que las anotaciones de Java se utilizan de manera similar.

Por ejemplo, la anotación TileNetworkData definida en su ejemplo está decorada con una anotación Retention(RetentionPolicy.RUNTIME). Esto le dice al compilador que incruste la anotación TileNetworkData en el bytecode para los campos que anota. La misma anotación también le dice al tiempo de ejecución de Java que, cuando carga clases con campos TileNetworkData-annotated, debe conservar la anotación TileNetworkData para la reflexión en tiempo de ejecución.

Ahora, su código puede reflexionar sobre los campos de un objeto de encontrar las anotaciones TileNetworkData y hacer algo con campos tan comentadas:

// I haven't even compiled this code, and even if it works, it's still insane. 
// (others who know annotations better should feel free to edit or replace) 
public void copyTileNetworkDataToCache (Object data, Cache<?> cache) { 
    for (Field f : data.getClass().getFields()) { 
    if (f.isAnnotationPresent(TileNetworkData.class)) { 
     cache.save(f.get(data)); 
    } 
    } 
} 

incluso se puede escribir código que enseña el compilador de Java how to interpret your annotations at compile time, utilizando el apt interfaz en los conmutadores JDK 5 y javac en JDK 6 y versiones posteriores. Para compensar otro ejemplo poco convincente, acceder a la red de teselas puede llevar tanto tiempo que no desee usar datos siempre que sea posible. Por lo tanto, es posible que desee hacer una lista de todas las clases que incluyen campos con anotaciones en TileNetworkData, para que pueda revisarlas todas y posiblemente reescribir las que no necesitan absolutamente acceder a la red de teselas. Para hacerlo, puede escribir un procesador de anotaciones que imprima todas las clases coincidentes, luego apunte apt en el procesador cuando realice la compilación.

2

Las anotaciones se utilizan para metadatos, para describir métodos, clases y otros tipos de objetos.

Puede usar el para asignar metadatos (descripciones de los datos) a sus clases de Java. El ejemplo clásico es @Deprecated, que marca un método como 'no se utilizará en el futuro'.

Por ejemplo, puede usarlos para agregar información de configuración a una clase java. Si está utilizando Hibernate (un ORM), agrega anotaciones a la clase diciendo que esta clase debe completarse a partir de la información contenida en la tabla de la base de datos table_xxx, y la información de la columna column_xxx debe almacenarse en dicho campo de la clase.

El código que ha publicado está definiendo la Anotación. Esto permitirá que esta Anotación se use en otro lugar de tu código. Se dice que la anotación estará disponible en tiempo de ejecución, @Retention(RetentionPolicy.RUNTIME), y que la Anotación debe estar disponible tanto para la clase que la usa como para cualquier subclase de esa clase.

Para obtener más información, ver las respuestas a How and where are Annotations used in Java?

+0

Esto no responde exactamente lo que el OP está preguntando específicamente. – BoltClock

1

Los metadatos se pueden consultar a través de la reflexión. Por lo tanto, si hubiera un genérico void submitTileNetworkData(Object model) en algún lugar del código, podría iterar sobre los campos de model y construir un volcado binario basado en anotaciones TileNetworkData.

4

Ejemplo: Transacción demarcación:

public class TransactionalThing { 
    @Transactional 
    public void doSomePersistenceStuff() { 
     Foo foo = loadAFoo(); 
     doSomeStuffWith(foo); 
     foo.setProcessed(true); 
    } 
} 

No habría otro código que busca métodos anotados por @Transactional, inicia una transacción antes de que se llama el método, y se compromete (o deshace) la transacción cuando termina . También se puede poner la información en la anotación de cosas como, por ejemplo, las reglas de rollback:

@Transactional(rollbackFor = SomeException.class, 
       noRollbackFor = SomeOtherException.class) 

y otra vez, es sólo hasta el código que analiza estas transacciones para leer en esos atributos y manejar las cosas adecuadamente.

Cuestiones relacionadas