anotaciones - crear annotation en java
¿Por qué no es posible extender las anotaciones en Java? (8)
No entiendo por qué no hay herencia en las anotaciones de Java, al igual que las clases de Java. Creo que sería muy útil.
Por ejemplo: quiero saber si una anotación dada es un validador. Con la herencia, podría navegar reflexivamente a través de superclases para saber si esta anotación extiende una ValidatorAnnotation
. De lo contrario, ¿cómo puedo lograr esto?
Entonces, ¿alguien puede darme una razón para esta decisión de diseño?
En cierto sentido, ya lo tienes con Annotations - meta Annotations. Si anota una anotación con metainformación, esto equivale en muchos aspectos a extender una interfaz adicional. Las anotaciones son interfaces, por lo que el polimorfismo no entra realmente en juego, y como son de naturaleza estática, no puede haber un despacho dinámico en tiempo de ejecución.
En su ejemplo de validador, podría simplemente obtener en la anotación el tipo anotado y ver si tiene una meta-anotación de validador.
El único caso de uso que podría ver que la herencia ayudaría es si quisiera obtener la anotación por supertipo, pero eso agregaría un montón de complejidad, porque un método o tipo dado puede tener dos anotaciones de este tipo, lo que significa que se debería devolver una matriz en lugar de un solo objeto.
Así que creo que la respuesta definitiva es que los casos de uso son esotéricos y complican los casos de uso más estándar, por lo que no vale la pena.
Las anotaciones extensibles agregarían efectivamente la carga de especificar y mantener otro tipo de sistema. Y este sería un sistema de tipo bastante único, por lo que no podría simplemente aplicar un paradigma de tipo OO.
Piense en todos los problemas cuando introduzca polimorfismo y herencia en una anotación (por ejemplo, ¿qué sucede cuando la subnotación cambia las especificaciones de la meta-anotación, como la retención?)
¿Y toda esta complejidad añadida para qué uso?
¿Quieres saber si una anotación dada pertenece a una categoría?
Prueba esto:
@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
String category();
}
@Category(category="validator")
public @interface MyFooBarValidator {
}
Como puede ver, puede agrupar y clasificar fácilmente las anotaciones sin molestias utilizando las instalaciones proporcionadas.
Entonces, KISS es la razón para no introducir un sistema de tipo meta-tipo en el lenguaje Java.
[ps edit]
Utilicé el String simplemente como demostración y en vista de una meta anotación abierta. Para su propio proyecto dado, obviamente puede usar una enumeración de tipos de categorías y especificar múltiples categorías ("herencia múltiple") para una anotación dada. Tenga en cuenta que los valores son totalmente falsos y solo para fines de demostración:
@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
AnnotationCategory[] category();
}
public enum AnnotationCategory {
GENERAL,
SEMANTICS,
VALIDATION,
ETC
}
@Category(category={AnnotationCategory.GENERAL, AnnotationCategory.SEMANTICS})
public @interface FooBarAnnotation {
}
Los diseñadores del soporte de anotación de Java hicieron una serie de "simplificaciones" en detrimento de la comunidad de Java.
Ningún subtipo de anotaciones hace que muchas anotaciones complejas sean innecesariamente feas. Uno no puede simplemente tener un atributo dentro de una anotación que pueda contener una de tres cosas. Uno debe tener tres atributos separados, lo que confunde a los desarrolladores y requiere la validación en tiempo de ejecución para garantizar que solo se use uno de los tres.
Sólo una anotación de un tipo dado por sitio. Esto ha llevado a un patrón de anotación de colección completamente innecesario. @Validation y @Validations, @Image y @Images, etc.
El segundo está siendo remediado en Java 8, pero es demasiado tarde. Se han escrito muchos marcos basados en lo que era posible en Java 5 y ahora estas API verrugas están aquí para quedarse por un buen tiempo.
Nunca pensé en eso, pero ... parece que tienes razón, no hay ningún problema con la facilidad de herencia de anotaciones (al menos no veo el problema).
Acerca de su ejemplo con anotación ''validador'' : puede explotar el enfoque de ''meta-anotación'' en ese momento. Es decir, aplica una meta-anotación particular a toda la interfaz de anotación.
Podría tardar tres años en responder a esta pregunta, pero me pareció interesante porque me encontré en el mismo lugar. Aquí está mi opinión sobre ello. Puedes ver las anotaciones como Enums. Proporcionan un tipo de información unidireccional: la utilizan o la pierden.
Tuve una situación en la que quería simular GET, POST, PUT y DELETE en una aplicación web. Tenía tantas ganas de tener una anotación "super" que se llamaba "HTTP_METHOD". Más tarde me di cuenta de que no importaba. Bueno, tuve que conformarme con el uso de un campo oculto en el formulario HTML para identificar DELETE y PUT (porque POST y GET estaban disponibles de todos modos).
En el lado del servidor, busqué un parámetro de solicitud oculto con el nombre "_método". Si el valor era PUT o DELETE, entonces anuló el método de solicitud HTTP asociado. Dicho esto, no importaba si necesitaba o no extender una anotación para hacer el trabajo. Todas las anotaciones parecían iguales, pero fueron tratadas de manera diferente en el lado del servidor.
Así que en su caso, deje caer la picazón para extender las anotaciones. Trátelos como ''marcadores''. Ellos "representan" cierta información y no necesariamente "manipulan" alguna información.
Sobre la razón por la cual no fue diseñado de esa manera, puede encontrar la respuesta en las Preguntas frecuentes de diseño de JSR 175 , donde dice:
¿Por qué no admite los subtipos de anotación (donde un tipo de anotación se extiende a otro)?
Complica el sistema de tipo de anotación y hace que sea mucho más difícil escribir "Herramientas específicas".
...
“Herramientas específicas”: programas que consultan tipos conocidos de anotación de programas externos arbitrarios. Los generadores de trozos, por ejemplo, entran en esta categoría. Estos programas leerán las clases anotadas sin cargarlas en la máquina virtual, pero cargarán las interfaces de anotación.
Entonces, sí, supongo, la razón es que solo KISS. De todos modos, parece que este problema (junto con muchos otros) se está analizando como parte de JSR 308 , e incluso puedes encontrar un compilador alternativo con esta funcionalidad ya desarrollada por Mathias Ricken .
Una cosa en la que podría pensar es en la posibilidad de tener múltiples anotaciones. Así que puedes agregar un validador y una anotación más específica en el mismo lugar. Pero podría estar equivocado :)
el mismo problema que tengo No, no puedes. Me "discipliné" a mí mismo para escribir las propiedades en las anotaciones para respetar algunos estándares, por lo que fuera de ellas, puede "oler" qué tipo de anotación es por las propiedades que tiene.