2009-05-13 15 views
5

He añadido recientemente a la RI de JSR305 en mi proyecto y han estado agregando anotaciones a mis interfaces de la siguiente manera:¿Es esta la forma correcta de usar javax.annotation de JSR305?

public interface AccountService 
{ 
    @Nullable AccountResult consolidate(@Nonnull Date from, @Nonnull Date to) 
} 

En el espíritu de la JSR (tal como se describe aquí), ¿cree que soy hacer mal uso de las anotaciones al usarlas en las interfaces? Quiero indicar que el valor de retorno puede ser nulo, pero creo que @Nullable se aplica más al método "consolidar". No los agrego a las implementaciones porque cuando estoy codificando, el código de la interfaz es mi luz guía.

+1

¿Cuál sería otra interpretación de un método anulable, diferente al significado que pretendes expresar (el valor de retorno puede ser nulo)? – Thilo

Respuesta

1

Creo que depende de por qué está agregando las anotaciones.

Si solo los está agregando como referencia para que los implementadores de la interfaz conozcan su diseño previsto, está bien.

Utilizo anotaciones para el procesamiento transaccional y la aplicación de la función de seguridad, por lo que mis anotaciones están en el nivel de implementación. Lo bueno de esto es que el procesador AOP en mi contenedor Spring puede probar la presencia de esta o aquella anotación y aplicar clases de proxy apropiadas para hacer cosas como definir un límite transaccional o asegurar que el usuario esté autorizado para alguna llamada a método particular.

Por lo tanto, si tiene previsto eliminar cualquier proceso de la presencia o ausencia de la anotación, asegúrese de que su implementación esté anotada. Si es solo para referencia, está bien anotar solo la interfaz.

6

Puede ver '@NonNull String' como una subclase estricta de String. Después de todo, cualquier cadena no nula es definitivamente una 'instancia de' '@Nullable String', pero cualquier instancia de '@Nullable String' puede no ser una instancia de '@NonNull String' (no lo sería si fuera nulo, por ejemplo).

Viéndolo de esta manera, @Nullable y @NonNull son información de tipo, y por lo tanto son perfectamente razonables en las interfaces. Está indicando a los implementadores que pueden devolver nulo, y que no tienen que preocuparse por nulos de entrada, y está indicando a las personas que llaman que no deben pasar nulo, y que deben esperar nulos.

Por supuesto, aunque todo esto es muy razonable, vanilla javac v1.6 ciertamente no aplica ninguna de estas reglas de la misma manera que impone la seguridad de tipo para los tipos reales. Pero uno puede soñar, o uno podría usar algo como pmd o findbugs para tomar el trabajo de verificar estas anotaciones.

Las anotaciones @NonNull y @Nullable no son suficientes para un sistema completo de tipeo de nulidad. Realmente no sé por qué JSR305 no aborda esto, pero hay un tercer tipo: "@MaybeNull". Aparecería dentro de los parámetros genéricos; en cualquier otro lugar tendría el mismo significado que @Nullable.

pública addIfNotNull static void (Lista < @MaybeNull T> lista, @Nullable T elemento) { si (punto! = Null) list.add (punto); }

Si la anotación en la primera 'T' es "@Nullable", entonces no podría pasar listas no nulas, lo que haría una API bastante inútil. Por otro lado, si fuera @NonNull, no podría pasar una lista anulable. En la práctica, no importa qué se mueva allí, (A) nunca causará una NullPointerException y (B) nunca violar la anotación Entonces, necesitas una forma de expresarlo: no me importa si esta 'T' en particular es Nullable o no; Voy a anular la verificación cuando leo de ella, y nunca escribiré nulos, por lo que no importa.

La diferencia entre @MaybeNull y @Nullable es análoga a la diferencia entre '? extiende Número 'y' Número 'en genéricos. Fuera de los genéricos, significan lo mismo, pero en los genéricos hay una diferencia.

Por lo tanto, no mantenga sus esperanzas de una revisión de tipo rígida en el corto plazo.

@ Heredado solo funciona para las clases, pero se podría imaginar algo similar para los tipos anotados de devolución y los parámetros anotados.

+0

@MaybeNull fue eliminado de JSR305, hasta donde yo sé. Además, las anotaciones sobre los tipos genéricos están especificadas por JSR308, que estará disponible en Java7. (NOTA: solo se activará este ** hecho ** de que puede anotar tipos genéricos, no todas las colecciones de anotaciones predefinidas). –

Cuestiones relacionadas