instalar - java 7 download
¿Qué anotación @NotNull de Java debo usar? (20)
Androide
Esta respuesta es específica de Android. Android tiene un paquete de soporte llamado support-annotations
. Esto proporciona dozens de anotaciones http://tools.android.com/tech-docs/support-annotations de http://tools.android.com/tech-docs/support-annotations y también proporciona algunas comunes como NonNull
, Nullable
, etc.
Para agregar un paquete de anotaciones de soporte , agregue la siguiente dependencia en su build.gradle:
compile ''com.android.support:support-annotations:23.1.1''
y luego usar:
import android.support.annotation.NonNull;
void foobar(@NonNull Foo bar) {}
Estoy buscando hacer que mi código sea más legible, así como utilizar herramientas como la inspección de códigos IDE y / o el análisis de códigos estáticos (FindBugs y Sonar) para evitar las NullPointerExceptions. Muchas de las herramientas parecen incompatibles con la @NotNull
de @NotNull
/ @NonNull
/ @Nonnull
y enumerarlas todas en mi código sería terrible de leer. ¿Alguna sugerencia de cuál es el ''mejor''? Aquí está la lista de anotaciones equivalentes que he encontrado:
javax.validation.constraints.NotNull
Creado para la validación en tiempo de ejecución, no análisis estático.
documentationedu.umd.cs.findbugs.annotations.NonNull
Utilizado por el análisis estático de Findbugs y por lo tanto Sonar (ahora Sonarqube )
documentationjavax.annotation.Nonnull
Esto también podría funcionar con Findbugs, pero JSR-305 está inactivo. (Ver también: ¿Cuál es el estado de JSR 305? ) sourceorg.jetbrains.annotations.NotNull
Utilizado por IntelliJ IDEA IDE para el análisis estático.
documentationlombok.NonNull
Se utiliza para controlar la generación de código en el Proyecto Lombok .
Anotación de marcador de posición ya que no hay estándar.
source , documentationandroid.support.annotation.NonNull
Marcación de anotación disponible en Android, proporcionada por el paquete de anotaciones de soporte
documentationorg.eclipse.jdt.annotation.NonNull
Utilizado por Eclipse para el análisis de código estático
documentation
Como Oracle JSR-305 por el momento @NonNull (y @Nullable), me temo que no hay una buena respuesta. Todo lo que podemos hacer es encontrar una solución pragmática y la mía es la siguiente:
Sintaxis
Desde un punto de vista puramente estilístico, me gustaría evitar cualquier referencia a IDE, framework o cualquier kit de herramientas, excepto a Java.
Esto descarta:
- android.support.annotation
- edu.umd.cs.findbugs.annotations
- org.eclipse.jdt.annotation
- org.jetbrains.annotations
- org.checkerframework.checker.nullness.qual
- lombok.NonNull
Lo que nos deja con javax.validation.constraints o javax.annotation. El primero viene con JEE. Si esto es mejor que javax.annotation, que puede llegar eventualmente con JSE o nunca, es un tema de debate. Personalmente prefiero javax.annotation porque no me gustaría la dependencia JEE.
Esto nos deja con
javax.annotation
que es también el más corto.
Solo hay una sintaxis que incluso sería mejor: java.annotation.Nullable. Como otros paquetes pasaron de javax a java en el pasado, javax.annotation sería un paso en la dirección correcta.
Implementación
Esperaba que todos tuvieran básicamente la misma implementación trivial, pero un análisis detallado mostró que esto no es cierto.
Primero por las similitudes:
Las anotaciones de @NonNull tienen la línea
public @interface NonNull {}
excepto por
- org.jetbrains.annotations que lo llama @NotNull y tiene una implementación trivial
- javax.annotation que tiene una implementación más larga
- javax.validation.constraints que también lo llama @NotNull y tiene una implementación
Todas las anotaciones @Nullable tienen la línea
public @interface Nullable {}
excepto por (nuevamente) las org.jetbrains.annotations con su implementación trivial.
Por las diferencias:
Una sorprendente es que
- javax.annotation
- javax.validation.constraints
- org.checkerframework.checker.nullness.qual
todos tienen anotaciones en tiempo de ejecución (@Retention (RUNTIME), mientras que
- android.support.annotation
- edu.umd.cs.findbugs.annotations
- org.eclipse.jdt.annotation
- org.jetbrains.annotations
son solo el tiempo de compilación (@Retention (CLASS)).
Como se describe en esta respuesta SO, el impacto de las anotaciones en tiempo de ejecución es menor de lo que uno podría pensar, pero tienen la ventaja de que las herramientas permiten realizar comprobaciones en tiempo de ejecución además de las de tiempo de compilación.
Otra diferencia importante es en qué parte del código se pueden usar las anotaciones. Hay dos enfoques diferentes. Algunos paquetes utilizan contextos de estilo JLS 9.6.4.1. La siguiente tabla da una visión general:
FIELD METHOD PARAMETER LOCAL_VARIABLE android.support.annotation X X X edu.umd.cs.findbugs.annotations X X X X org.jetbrains.annotation X X X X lombok X X X X javax.validation.constraints X X X
org.eclipse.jdt.annotation, javax.annotation y org.checkerframework.checker.nullness.qual utilizan los contextos definidos en JLS 4.11, que en mi opinión es la forma correcta de hacerlo.
Esto nos deja con
- javax.annotation
- org.checkerframework.checker.nullness.qual
en esta ronda
Código
Para ayudarlo a comparar más detalles usted mismo, enumero el código de cada anotación a continuación. Para facilitar la comparación, eliminé los comentarios, las importaciones y la anotación @Documented. (todos tenían @Documented excepto las clases del paquete de Android). Reordené las líneas y los campos @Target y normalicé las calificaciones.
package android.support.annotation;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER})
public @interface NonNull {}
package edu.umd.cs.findbugs.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}
package org.eclipse.jdt.annotation;
@Retention(CLASS)
@Target({ TYPE_USE })
public @interface NonNull {}
package org.jetbrains.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NotNull {String value() default "";}
package javax.annotation;
@TypeQualifier
@Retention(RUNTIME)
public @interface Nonnull {
When when() default When.ALWAYS;
static class Checker implements TypeQualifierValidator<Nonnull> {
public When forConstantValue(Nonnull qualifierqualifierArgument,
Object value) {
if (value == null)
return When.NEVER;
return When.ALWAYS;
}
}
}
package org.checkerframework.checker.nullness.qual;
@Retention(RUNTIME)
@Target({TYPE_USE, TYPE_PARAMETER})
@SubtypeOf(MonotonicNonNull.class)
@ImplicitFor(
types = {
TypeKind.PACKAGE,
TypeKind.INT,
TypeKind.BOOLEAN,
TypeKind.CHAR,
TypeKind.DOUBLE,
TypeKind.FLOAT,
TypeKind.LONG,
TypeKind.SHORT,
TypeKind.BYTE
},
literals = {LiteralKind.STRING}
)
@DefaultQualifierInHierarchy
@DefaultFor({TypeUseLocation.EXCEPTION_PARAMETER})
@DefaultInUncheckedCodeFor({TypeUseLocation.PARAMETER, TypeUseLocation.LOWER_BOUND})
public @interface NonNull {}
Para completar, aquí están las implementaciones de @Nullable:
package android.support.annotation;
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD})
public @interface Nullable {}
package edu.umd.cs.findbugs.annotations;
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
@Retention(CLASS)
public @interface Nullable {}
package org.eclipse.jdt.annotation;
@Retention(CLASS)
@Target({ TYPE_USE })
public @interface Nullable {}
package org.jetbrains.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface Nullable {String value() default "";}
package javax.annotation;
@TypeQualifierNickname
@Nonnull(when = When.UNKNOWN)
@Retention(RUNTIME)
public @interface Nullable {}
package org.checkerframework.checker.nullness.qual;
@Retention(RUNTIME)
@Target({TYPE_USE, TYPE_PARAMETER})
@SubtypeOf({})
@ImplicitFor(
literals = {LiteralKind.NULL},
typeNames = {java.lang.Void.class}
)
@DefaultInUncheckedCodeFor({TypeUseLocation.RETURN, TypeUseLocation.UPPER_BOUND})
public @interface Nullable {}
Los siguientes dos paquetes no tienen @Nullable, así que los enumero por separado lombok tiene un @NonNull bastante aburrido. En javax.validation.constraints el @NonNull es en realidad un @NotNull y tiene una implementación bastante larga.
package lombok;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}
package javax.validation.constraints;
@Retention(RUNTIME)
@Target({ FIELD, METHOD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Constraint(validatedBy = {})
public @interface NotNull {
String message() default "{javax.validation.constraints.NotNull.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default {};
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@interface List {
NotNull[] value();
}
}
Apoyo
Desde mi punto de vista, javax.annotation es al menos compatible con Eclipse y el marco de trabajo de Checker.
Resumen
Mi anotación ideal sería la sintaxis de java.annotation con la implementación de Checker Framework.
Si no tiene la intención de usar el Marco del Verificador, la javax.annotation ( JSR-305 ) sigue siendo su mejor apuesta por el momento.
Si está dispuesto a comprar en el Marco de Checker, simplemente use su org.checkerframework.checker.nullness.qual.
Fuentes
- android.support.annotation de android-5.1.1_r1.jar
- edu.umd.cs.findbugs.annotations de findbugs-annotations-1.0.0.jar
- org.eclipse.jdt.annotation desde org.eclipse.jdt.annotation_2.1.0.v20160418-1457.jar
- org.jetbrains.annotations de jetbrains-anotaciones-13.0.jar
- javax.annotation de gwt-dev-2.5.1-sources.jar
- org.checkerframework.checker.nullness.qual from checker-framework-2.1.9.zip
- lombok de lombok commit f6da35e4c4f3305ecd1b415e2ab1b9ef8a9120b4
- javax.validation.constraints from validation-api-1.0.0.GA-sources.jar
De acuerdo con la lista de características de Java 7, las anotaciones de tipo JSR-308 se difieren a Java 8. Las anotaciones JSR-305 ni siquiera se mencionan.
Hay un poco de información sobre el estado de JSR-305 en un appendix del último borrador JSR-308. Esto incluye la observación de que las anotaciones JSR-305 parecen estar abandonadas. La página JSR-305 también lo muestra como "inactivo".
Mientras tanto, la respuesta pragmática es utilizar los tipos de anotación que son compatibles con las herramientas más utilizadas ... y estar preparado para cambiarlos si la situación cambia.
De hecho, JSR-308 no define ningún tipo de anotación / clases, y parece que piensan que está fuera del alcance. (Y tienen razón, dada la existencia de JSR-305).
Sin embargo, si JSR-308 realmente parece estar en Java 8, no me sorprendería si el interés en JSR-305 reviviera. AFAIK, el equipo JSR-305 no ha abandonado formalmente su trabajo. Han estado callados por más de 2 años.
Es interesante que Bill Pugh (el líder tecnológico para JSR-305) es uno de los tipos detrás de FindBugs.
Desafortunadamente, JSR 308
no agregará más valores que la sugerencia local de No Nulo de este proyecto aquí
Java 8
no vendrá con una única anotación predeterminada o su propio marco de Checker
. Similar a Find-bugs o JSR 305
, este JSR está mal mantenido por un pequeño grupo de equipos en su mayoría académicos.
No hay poder comercial detrás de él, por lo que JSR 308
lanza EDR 3
(Early Draft Review en JCP
) AHORA, mientras que Java 8
se envía en menos de 6 meses: -O es similar a 310
btw. pero a diferencia de 308 Oracle
ha hecho cargo de eso ahora lejos de sus fundadores para minimizar el daño que causará a la Plataforma Java.
Cada proyecto, proveedor y clase académica, como los que se encuentran detrás del Checker Framework
y JSR 308
, crearán su propia anotación de comprobador de propiedad.
Hacer que el código fuente sea incompatible en los próximos años, hasta que se puedan encontrar algunos compromisos populares que se puedan agregar a Java 9
o 10
, o mediante marcos como Apache Commons
o Google Guava
;-)
Distinguir entre análisis estático y análisis en tiempo de ejecución. Use el análisis estático para las cosas internas y el análisis de tiempo de ejecución para los límites públicos de su código.
Para cosas que no deben ser nulas:
Verificación de tiempo de ejecución: use "if (x == null) ..." (dependencia cero) o @ javax.validation.NotNull (con validación de bean) o @ lombok.NonNull (simple y llano) o guavas Preconditions.checkNotNull (.. .)
- Uso Opcional para tipos de retorno de método (solo). Ya sea Java8 o guayaba.
Comprobación estática: utilizar una anotación @NonNull
- Donde corresponda, use las anotaciones @ ... NonnullByDefault a nivel de clase o paquete. Cree estas anotaciones usted mismo (los ejemplos son fáciles de encontrar).
- De lo contrario, use @ ... CheckForNull en devoluciones de métodos para evitar NPEs
Esto debería dar el mejor resultado: advertencias en el IDE, errores de Findbugs y checkerframework, excepciones de tiempo de ejecución significativas.
No espere que las comprobaciones estáticas estén maduras, su denominación no está estandarizada y diferentes bibliotecas e IDE las tratan de manera diferente, ignorándolas. Las clases JSR305 javax.annotations. * Se ven como estándar, pero no lo son, y causan paquetes divididos con Java9 +.
Algunas notas explicaciones:
- Findbugs / spotbugs / jsr305 anotaciones con el paquete javax.validation. * Choca con otros módulos en Java9 +, también posiblemente viola la licencia de Oracle
- Las anotaciones de Spotbugs aún dependen de las anotaciones jsr305 / findbugs en tiempo de compilación (en el momento de escribir https://github.com/spotbugs/spotbugs/issues/421 )
- jetbrains @NotNull nombre está en conflicto con @ javax.validation.NotNull.
- Las anotaciones de jetbrains, eclipse o checkersframework para la verificación estática tienen la ventaja sobre javax.annotations de que no chocan con otros módulos en Java9 y superior
- @ javax.annotations.Nullable no significa para Findbugs / Spotbugs lo que usted (o su IDE) piensan que significa. Findbugs lo ignorará (en los miembros). Triste pero cierto.
- Para la verificación estática fuera de un IDE, existen 2 herramientas gratuitas: Spotbugs (anteriormente Findbugs) y checkersframework.
- La biblioteca de Eclipse tiene @NonNullByDefault, jsr305 solo tiene @ParametersAreNonnullByDefault. Esos son simples envoltorios de conveniencia que aplican anotaciones base a todo en un paquete (o clase), usted puede crear fácilmente los suyos. Esto se puede utilizar en el paquete. Esto puede entrar en conflicto con el código generado (por ejemplo, lombok).
- Las anotaciones de Eclipse jdt no son aplicables a devoluciones de métodos estáticos y algunos otros casos
- Debe evitarse el uso de lombok como una dependencia exportada para las bibliotecas que comparte con otras personas, cuanto menos dependientes transitivos, mejor
- El uso del marco de validación de Bean es poderoso, pero requiere una gran sobrecarga, por lo que es demasiado para evitar la comprobación manual de nulos.
- El uso de Opcional para campos y parámetros de método es controvertido (puede encontrar artículos al respecto fácilmente)
- Las anotaciones nulas de Android son parte de la biblioteca de soporte de Android, vienen con muchas otras clases y no juegan bien con otras anotaciones / herramientas.
Antes de Java9, esta es mi recomendación:
// file: package-info.java
@javax.annotation.ParametersAreNonnullByDefault
package example;
// file: PublicApi
package example;
public class PublicApi {
/**
* @param firstname MUST NOT be null
* @param lastname MUST NOT be null
*/
public Person createPerson(
// Spotbugs ignores the param annotations, but IDEs will show problems
@Nullable String firstname, // Users might send null
@Nullable String lastname // Users might send null
) {
if (firstname == null) throw new IllagalArgumentException(...);
if (lastname == null) throw new IllagalArgumentException(...);
return doCreatePerson(fistname, lastname, nickname);
}
@NonNull // Spotbugs checks that method cannot return null
private Person doCreatePerson(
String firstname, // Spotbugs checks null cannot be passed, because package has ParametersAreNonnullByDefault
String lastname,
@Nullable String nickname // tell Spotbugs null is ok
) {
return new Person(firstname, lastname, nickname);
}
@CheckForNull // Do not use @Nullable here, Spotbugs will ignore it, though IDEs respect it
private Person getNickname(
String firstname,
String lastname) {
return NICKNAMES.get(firstname + '':'' + lastname);
}
}
Tenga en cuenta que no hay forma de hacer que Spotbugs emita una advertencia cuando se elimina la referencia a un parámetro de método que puede contener nulos (en el momento de escribir esta versión, la versión 3.1 de Spotbugs). Tal vez checkerframework puede hacer eso.
Eclipse también tiene sus propias anotaciones.
org.eclipse.jdt.annotation.NonNull
Consulte en http://wiki.eclipse.org/JDT_Core/Null_Analysis para más detalles.
Hay otra manera de hacer esto en Java 8. Estoy haciendo 2 cosas para lograr lo que necesitaba:
- Haciendo campos anulables explícitos con tipos envolviendo campos anulables con
java.util.Optional
- Comprobación de que todos los campos no anulables no son nulos en tiempo de construcción con
java.util.Objects.requireNonNull
Ejemplo:
import static java.util.Objects.requireNonNull;
public class Role {
private final UUID guid;
private final String domain;
private final String name;
private final Optional<String> description;
public Role(UUID guid, String domain, String name, Optional<String> description) {
this.guid = requireNonNull(guid);
this.domain = requireNonNull(domain);
this.name = requireNonNull(name);
this.description = requireNonNull(description);
}
Así que mi pregunta es, ¿incluso necesitamos anotar cuando usamos Java 8?
Editar: Más tarde descubrí que algunos consideran una mala práctica utilizar Optional
en los argumentos, hay una buena discusión con pros y contras aquí ¿Por qué Java 8 de Opcional No se admitirán en argumentos
JSR305 y FindBugs son creados por la misma persona. Ambos están mal mantenidos, pero son tan estándar como son y son compatibles con todas las IDE principales. La buena noticia es que funcionan bien como están.
Aquí se explica cómo aplicar @Nonnull a todas las clases, métodos y campos de forma predeterminada. Consulte https://.com/a/13319541/14731 y https://.com/a/9256595/14731
- Definir
@NotNullByDefault
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;
/**
* This annotation can be applied to a package, class or method to indicate that the class fields,
* method return types and parameters in that element are not null by default unless there is: <ul>
* <li>An explicit nullness annotation <li>The method overrides a method in a superclass (in which
* case the annotation of the corresponding parameter in the superclass applies) <li> there is a
* default parameter annotation applied to a more tightly nested element. </ul>
* <p/>
* @see https://.com/a/9256595/14731
*/
@Documented
@Nonnull
@TypeQualifierDefault(
{
ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.LOCAL_VARIABLE,
ElementType.METHOD,
ElementType.PACKAGE,
ElementType.PARAMETER,
ElementType.TYPE
})
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNullByDefault
{
}
2. Agregue la anotación a cada paquete: package-info.java
@NotNullByDefault
package com.example.foo;
ACTUALIZACIÓN : A partir del 12 de diciembre de 2012, JSR 305 aparece como "Inactivo". Según la documentación:
Un JSR que fue votado como "inactivo" por el Comité Ejecutivo, o uno que ha llegado al final de su vida natural.
Parece que JSR-308 está convirtiendo en JDK 8 y aunque JSR no define @NotNull, el Checkers Framework
acompaña sí lo hace. En el momento de escribir este artículo, el complemento de Maven no se puede utilizar debido a este error: https://github.com/typetools/checker-framework/issues/183
Me gusta mucho el Checker Framework , que es una implementación de anotaciones de tipo ( JSR-308 ) que se utiliza para implementar comprobadores de defectos como un comprobador de nulidad. Realmente no he intentado que ningún otro ofrezca comparación, pero estoy feliz con esta implementación.
No estoy afiliado al grupo que ofrece el software, pero soy un fan.
Cuatro cosas que me gustan de este sistema:
Tiene un nullness defectos para la nullness (@Nullable), pero también tiene unos para la immutability y la interning (y otros). Uso el primero (nulidad) y trato de usar el segundo (inmutabilidad / IGJ). Estoy probando el tercero, pero aún no estoy seguro de usarlo a largo plazo. Todavía no estoy convencido de la utilidad general de los otros revisores, pero es bueno saber que el marco en sí es un sistema para implementar una variedad de anotaciones y comprobadores adicionales.
La configuración predeterminada para la comprobación de nulidad funciona bien: no nulo excepto locals (NNEL). Básicamente, esto significa que, de forma predeterminada, el comprobador trata todo (variables de instancia, parámetros de método, tipos genéricos, etc.) excepto las variables locales como si tuvieran un tipo @NonNull de forma predeterminada. Según la documentación:
El valor predeterminado de NNEL conduce a la menor cantidad de anotaciones explícitas en su código.
Puede establecer un valor predeterminado diferente para una clase o para un método si NNEL no funciona para usted.
Este marco le permite usar sin crear una dependencia en el marco al incluir sus anotaciones en un comentario: por ejemplo,
/*@Nullable*/
. Esto es bueno porque puede anotar y verificar una biblioteca o un código compartido, pero aún así puede usar esa biblioteca / código compartido en otro proyecto que no usa el marco. Esta es una buena característica. Me he acostumbrado a usarlo, aunque ahora tiendo a habilitar el Marco del Verificador en todos mis proyectos.El marco tiene una forma de anotar las API que usa y que aún no están anotadas para la nulidad usando archivos de código auxiliar.
Mientras espera que esto se solucione en sentido ascendente (¿Java 8?), También podría definir sus propias anotaciones @NotNull
y @Nullable
proyecto local. Esto también puede ser útil si está trabajando con Java SE, donde javax.validation.constraints
no está disponible de forma predeterminada.
import java.lang.annotation.*;
/**
* Designates that a field, return value, argument, or variable is
* guaranteed to be non-null.
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
@Documented
@Retention(RetentionPolicy.CLASS)
public @interface NotNull {}
/**
* Designates that a field, return value, argument, or variable may be null.
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
@Documented
@Retention(RetentionPolicy.CLASS)
public @interface Nullable {}
Esto debería admitirse en gran medida con fines decorativos o de prueba de futuro, ya que lo anterior obviamente no agrega soporte para el análisis estático de estas anotaciones.
Para los proyectos de Android, debe usar android.support.annotation.NonNull
y android.support.annotation.Nullable
. Estas y otras útiles anotaciones específicas de Android están disponibles en la Biblioteca de soporte .
De http://tools.android.com/tech-docs/support-annotations :
La biblioteca de soporte en sí también ha sido anotada con estas anotaciones, por lo que como usuario de la biblioteca de soporte, Android Studio ya verificará su código y marcará los problemas potenciales en función de estas anotaciones.
Si alguien está buscando las clases de IntelliJ: puede obtenerlas del repositorio de Maven con
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>15.0</version>
</dependency>
Si está desarrollando para Android, está un tanto atado a Eclipse (edición: al momento de escribir, ya no), que tiene sus propias anotaciones. Se incluye en Eclipse 3.8+ (Juno), pero está deshabilitado de forma predeterminada.
Puede habilitarlo en Preferencias> Java> Compilador> Errores / Advertencias> Análisis nulo (sección plegable en la parte inferior).
Marque "Habilitar análisis nulo basado en anotaciones"
http://wiki.eclipse.org/JDT_Core/Null_Analysis#Usage tiene recomendaciones sobre la configuración. Sin embargo, si tiene proyectos externos en su área de trabajo (como el SDK de Facebook), es posible que no cumplan con esas recomendaciones y probablemente no quiera corregirlos con cada actualización del SDK ;-)
Yo suelo:
- Acceso a puntero nulo: error
- Violación de la especificación nula: Error (vinculado al punto # 1)
- Posible acceso al puntero nulo: Advertencia (de lo contrario, el SDK de Facebook tendría advertencias)
- Conflicto entre anotaciones nulas e inferencia nula: Advertencia (vinculado al punto # 3)
Solo señalando que la API de validación de Java ( javax.validation.constraints.*
) No viene con una anotación @Nullable
, que es muy valiosa en un contexto de análisis estático. Tiene sentido para la validación del bean de tiempo de ejecución, ya que este es el valor predeterminado para cualquier campo no primitivo en Java (es decir, nada para validar / aplicar). Para los fines señalados, debe pesar hacia las alternativas.
Utilizo el IntelliJ, porque me preocupa principalmente el hecho de que IntelliJ marque cosas que puedan producir un NPE. Estoy de acuerdo en que es frustrante no tener una anotación estándar en el JDK. Se habla de agregarlo, podría hacerlo en Java 7. ¡En cuyo caso habrá uno más para elegir!
¿El sol no tiene el suyo ahora? Qué es esto:
http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-com.sun/istack/com.sun.istack.internal.htm
Esto parece estar empaquetado con todas las versiones de Java que he usado en los últimos años.
Edición: Como se menciona en los comentarios a continuación, probablemente no quieras usarlos. ¡En ese caso, mi voto es para las anotaciones de IntelliJ Jetbrains!
Otra opción es las anotaciones proporcionadas con antlr 4. Siguiendo Tire Solicitud # 434 , el artefacto que contiene el @NotNull
y @Nullable
anotaciones incluye un procesador de anotación que produce en tiempo de compilación errores y / o advertencias en el caso de uno de estos atributos se mal utilizados (por ejemplo, si ambos se aplican al mismo elemento, o si @Nullable
se aplican a un elemento con un tipo primitivo). El procesador de anotaciones proporciona una garantía adicional durante el proceso de desarrollo del software de que la información transmitida por la aplicación de estas anotaciones es precisa, incluso en casos de herencia de métodos.
Si está compilando su aplicación con Spring Framework, le sugeriría usar javax.validation.constraints.NotNull
proveniente de Beans Validation empaquetado en la siguiente dependencia:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
La principal ventaja de esta anotación es que Spring proporciona soporte para los parámetros de método y los campos de clase anotados con javax.validation.constraints.NotNull
. Todo lo que necesitas hacer para habilitar el soporte es:
suministre el api jar para la validación de beans y jar con la implementación del validador de las anotaciones jsr-303 / jsr-349 (que viene con la dependencia de Hibernate Validator 5.x):
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.1.Final</version> </dependency>
proporcionar MethodValidationPostProcessor al contexto de Spring
@Configuration @ValidationConfig public class ValidationConfig implements MyService { @Bean public MethodValidationPostProcessor providePostProcessor() { return new MethodValidationPostProcessor() } }
Finalmente, anotará sus clases con Spring''s
org.springframework.validation.annotation.Validated
y la validación será manejada automáticamente por Spring.
Ejemplo:
@Service
@Validated
public class MyServiceImpl implements MyService {
@Override
public Something doSomething(@NotNull String myParameter) {
// No need to do something like assert myParameter != null
}
}
Cuando intentes llamar al método doSomething y pasar null como valor de parámetro, se lanzará spring (por medio de HibernateValidator) ConstraintViolationException
. No hay necesidad de trabajo manual aquí.
También puede validar valores de retorno.
Otro beneficio importante de javax.validation.constraints.NotNull
venir para Beans Validation Framework es que en este momento todavía está desarrollado y se están planificando nuevas funciones para la nueva versión 2.0.
¿Qué hay de @Nullable
? No hay nada de eso en Beans Validation 1.1. Bueno, podría argumentar que si usted decide usar más @NotNull
de lo que NO se anota @NonNull
es efectivamente "anulable", por lo que la @Nullable
anotación es inútil.
Si está trabajando en un proyecto grande, puede ser mejor que cree sus propias anotaciones @Nullable
o @NotNull
anotaciones.
Por ejemplo:
@java.lang.annotation.Documented
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)
@java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD,
java.lang.annotation.ElementType.METHOD,
java.lang.annotation.ElementType.PARAMETER,
java.lang.annotation.ElementType.LOCAL_VARIABLE})
public @interface Nullable
{
}
Si utiliza la política de retención correcta , las anotaciones no estarán disponibles en tiempo de ejecución . Desde ese punto de vista, es sólo una cosa interna .
Aunque esta no es una ciencia estricta, creo que tiene más sentido usar una clase interna para ello.
- Es una cosa interna. (sin impacto funcional o técnico)
- Con muchos, muchos, muchos usos.
- IDE como IntelliJ soporta aduana
@Nullable
/@NotNull
anotaciones. - La mayoría de los marcos prefieren usar su propia versión interna también.
Preguntas adicionales (ver comentarios):
¿Cómo configurar esto en IntelliJ?
Haga clic en el "oficial de policía" en la esquina inferior derecha de la barra de estado de IntelliJ. Y haga clic en "Configurar inspecciones" en la ventana emergente. Próximo ...
Una de las cosas buenas de IntelliJ es que no necesita usar sus anotaciones. Puedes escribir el tuyo propio o puedes usar los de cualquier otra herramienta que te guste. Ni siquiera estás limitado a un solo tipo. Si está utilizando dos bibliotecas que usan diferentes anotaciones de @NotNull, puede decirle a IntelliJ que use ambas. Para hacer esto, vaya a "Configurar inspecciones", haga clic en la inspección "Condiciones y excepciones constantes" y presione el botón "Configurar inspecciones". Utilizo el verificador de nulidad siempre que puedo, así que configuro IntelliJ para usar esas anotaciones, pero puede hacer que funcione con cualquier otra herramienta que desee. (No tengo una opinión sobre las otras herramientas porque he estado usando las inspecciones de IntelliJ durante años, y me encantan).