intellij-idea nullpointerexception guava inspection

Google-guava checkNotNull e IntelliJ IDEA "pueden producir java.lang.NullPointerException"



intellij-idea inspection (6)

A través de una combinación de anotaciones @Contract y la función Anotaciones externas, ahora puede anotar métodos de condiciones Preconditions para que IntelliJ aplique el análisis estático correcto a las llamadas a estos métodos.

Digamos que tenemos este ejemplo

public void doSomething(Object someArg) { Preconditions.checkArgument(someArg != null); someArg.doSomethingElse(); //currently gives NPE warning if (someArg != null) { //no warning that this is always true } }

En IntelliJ (estoy usando 13):

  • Navegue a Preconditions.checkArgument(boolean) .
  • Coloque el cursor sobre el nombre del método y presione Alt - Intro para que aparezca la ventana emergente de intenciones.
  • Seleccione "Agregar contrato de método".
  • Utilice el texto del contrato false -> fail .
  • Cuando se le solicite, proporcione una ubicación para el archivo de Anotaciones externas.

Ahora la advertencia en someArg.doSomethingElse() desaparece, e IDEA marcará, de hecho, la rama if como siempre.

Otros textos de contrato:

  • Preconditions.checkArgument(boolean, String) debe ser false, _ -> fail
  • Preconditions.checkNotNull(Object, String) debe ser null, _ -> fail ,
  • etcétera etcétera

Aquí está mi archivo completo annotations.xml para Preconditions :

<root> <item name=''com.google.common.base.Preconditions T checkNotNull(T)''> <annotation name=''org.jetbrains.annotations.Contract''> <val val="&quot;null -&gt; fail&quot;"/> </annotation> </item> <item name=''com.google.common.base.Preconditions T checkNotNull(T, java.lang.Object)''> <annotation name=''org.jetbrains.annotations.Contract''> <val val="&quot;null, _ -&gt; fail&quot;"/> </annotation> </item> <item name=''com.google.common.base.Preconditions T checkNotNull(T, java.lang.String, java.lang.Object...)''> <annotation name=''org.jetbrains.annotations.Contract''> <val val="&quot;null, _, _ -&gt; fail&quot;"/> </annotation> </item> <item name=''com.google.common.base.Preconditions void checkArgument(boolean)''> <annotation name=''org.jetbrains.annotations.Contract''> <val val="&quot;false -&gt; fail&quot;"/> </annotation> </item> <item name=''com.google.common.base.Preconditions void checkArgument(boolean, java.lang.Object)''> <annotation name=''org.jetbrains.annotations.Contract''> <val val="&quot;false, _ -&gt; fail&quot;"/> </annotation> </item> <item name=''com.google.common.base.Preconditions void checkArgument(boolean, java.lang.String, java.lang.Object...)''> <annotation name=''org.jetbrains.annotations.Contract''> <val val="&quot;false, _, _ -&gt; fail&quot;"/> </annotation> </item> <item name=''com.google.common.base.Preconditions void checkState(boolean)''> <annotation name=''org.jetbrains.annotations.Contract''> <val val="&quot;false -&gt; fail&quot;"/> </annotation> </item> <item name=''com.google.common.base.Preconditions void checkState(boolean, java.lang.Object)''> <annotation name=''org.jetbrains.annotations.Contract''> <val val="&quot;false, _ -&gt; fail&quot;"/> </annotation> </item> <item name=''com.google.common.base.Preconditions void checkState(boolean, java.lang.String, java.lang.Object...)''> <annotation name=''org.jetbrains.annotations.Contract''> <val val="&quot;false, _, _ -&gt; fail&quot;"/> </annotation> </item> </root>

Ver también

¿Hay alguna forma de suprimir esta advertencia?

MyClass object = null; /*Some code that ''might'' set this object but I know it will*/ Preconditions.checkNotNull(object); //when "assert object != null" is used here no warning is shown merged.setName(dRElement.getName()); //"May produce ''java.lang.NullPointerException''" warning here

Estoy usando IntelliJ IDEA 10.5 y sé que esta advertencia es innecesaria; sin embargo, me gustaría suprimirla aquí y evitar el apagado de las inspecciones.


Además de otras opciones, puedes probar-

Suprime las advertencias a nivel de método usando -

@SuppressWarnings({"NullableProblems"}) public void someMethod(){ ... ... }

o suprimir la advertencia a nivel de declaración mediante el uso de comentarios -

//noinspection NullableProblems someMethodCallProducingNullWarning(null);

Pero antes de hacer esto, asegúrese de que realmente no produzca NPE


De IntelliJ IDEA 14, no necesita preocuparse por esto.

@Nullable String extractPrefix(@Nullable String url) { if (StringUtils.isEmpty(url)) return null; if (url.startsWith("jar://")) { ...

Anteriormente, IntelliJ IDEA no tenía idea de que la ejecución del código ni siquiera llegaría a la llamada "startsWith" si la url es nula porque no se veía dentro de StringUtils.isEmpty. Por supuesto, puedes eliminar esas advertencias amarillas en extractPrefix mirando dentro de Escurrid y añadiendo un contrato "null -> true", ¡pero eso es muy aburrido! Eso es exactamente un trabajo para la computadora, no para usted, y ahora IntelliJ IDEA lo hace de manera automática, mirando el byte y el código fuente.

http://blog.jetbrains.com/idea/2014/10/automatic-notnullnullablecontract-inference-in-intellij-idea-14/


Existe un viejo problema en JetBrains Yourtrack para agregar este tipo de funcionalidad. Lo voté hace años, pero no veo una actividad. Si todos lo votan, entonces tendremos suerte.

Para aclarar el problema, se debe agregar la funcionalidad para que pueda etiquetar un método como la realización de algún tipo de verificación nula. Si eso sucediera, entonces podría escribir su propio contenedor para el método Precondiciones y anotarlo.

ACTUALIZACIÓN Me cansé de esperar por la funcionalidad, así que envié un parche yo mismo. Está disponible en 12.1.1 compilación 129.239. Para acceder a la configuración: Configuración> Inspecciones> Errores probables> Condiciones constantes y excepciones> Configurar métodos de confirmación / verificación.


Extrae un método?

private MyClass getMyClass() { /* This always returns an instance of MyClass, never null. */ } ... MyClass object = getMyClass(); Preconditions.checkNotNull(object); merged.setName(object.getName());