2011-03-02 14 views
21

Todos los métodos aceptan un conjunto de valores de parámetros. ¿Deberíamos siempre validar la no nulidad de los parámetros de entrada o permitir que el código falle con el clásico RunTimeException?¿Deberíamos siempre verificar cada parámetro del método en java para null en la primera línea?

He visto una gran cantidad de código donde la gente realmente no verifica la nulidad de los parámetros de entrada y simplemente escribe la lógica de negocios usando los parámetros. ¿Cuál es la mejor manera?

void public(String a, Integer b, Object c) 
{ 
    if(a == null || b == null || c == null) 
    { 
    throw new RunTimeException("Message..."); 
    } 
    .....business logic..... 
} 
+0

posible duplicado de [? Cuando para comprobar si un objeto es nulo o no] (http://stackoverflow.com/questions/706263/where-to-check-if -an-object-is-null-or-not) – NPE

+0

La otra pregunta es sobre '.net' pero es, en esencia, idéntica. – NPE

+0

Ninguna de las respuestas actuales menciona el uso de anotaciones y análisis estáticos, como FindBugs @NonNull, @CheckForNull, etc. Además, aunque no es un duplicado de la pregunta de .Net anterior, es probable que haya sido cubierto al menos una vez en stackoverflow . –

Respuesta

22

La mejor manera es solo marque cuando sea necesario.

Si su método es private, por ejemplo, para que sepa que nadie más lo está usando, y usted sabe que no está pasando ningún nulo, entonces no hay punto para comprobar nuevamente.

Sin embargo, si su método es public, quién sabe lo que los usuarios de su API intentarán hacer, así que es mejor que lo compruebe.

Si tiene dudas, marque.

Si lo mejor que puede hacer, sin embargo, es arrojar un NullPointerException, entonces puede que no quiera comprobar. Por ejemplo:

int getStringLength(String str) { 
    return str.length(); 
} 

Incluso si ha marcado para null, una opción razonable sería tirar un NullPointerException, que str.length() va a hacer por usted de todos modos.

+28

No recomendaría confiar en la NullPointerException automática en lugar de la validación explícita de argumentos. Dos razones: (a) la validación siempre debe ocurrir lo más temprano posible (piense que el método cambia algún estado antes de encontrarse con NPE) y (b) compatibilidad con el código. Un NPE en el cuerpo de la clase X irá primero al propietario de la clase X, ya que parece un error en la implementación. Sin embargo, si comprueba explícitamente args para null y throw dice IllegalArgumentException (también RuntimeException como NPE), entonces será obvio que el problema es con la persona que llama de la clase X. –

1

No veo mucho para hacer esto. Simplemente está replicando el comportamiento que obtendría de forma gratuita la primera vez que intenta operar en a, b o c.

0

Depende de lo que intenta hacer su código y de la situación en la que desea lanzar Exception. En algún momento deseará que su método arroje siempre una excepción si su método no podrá funcionar correctamente con valores nulos. Si su método puede funcionar alrededor de valores nulos, probablemente no sea necesario lanzar una excepción.

Agregar demasiadas excepciones comprobadas puede hacer que el código sea complicado y complicado. Esta fue la razón por la que no se incluyeron en C#.

1

No. Es normal suponer que los parámetros no serán nulos y que, de lo contrario, se lanzará una NullPointerException. Si su método permite que un parámetro sea nulo, debe indicarlo en su api.

1

Depende si espera que cualquiera de sus argumentos sea null - más precisamente, si su método todavía puede tomar una decisión correcta si algunos parámetros son null.

Si no es así, es una buena práctica para comprobar si hay null y elevar una excepción, porque de lo contrario obtendrá un NullPointerException, que nunca se debe coger, ya que su apariencia siempre indica que usted se olvidó de comprobar sus variables en el código. (y si lo atrapa, es posible que se pierda otras ocasiones en que se lanza, y puede presentar errores).

Por otro lado, si lanza RunTimeException o alguna otra excepción personalizada, puede manejarlo en algún lugar en el flujo ascendente, para que tenga más control sobre lo que sucede.

0

No, no deberías hacer eso universalmente.

Mis preferencias, con el fin, sería:

  1. hace algo razonable con el nula. Lo sensato de hacer depende completamente de la situación, pero lanzar una excepción personalizada no debe ser su primera opción.
  2. Utilice una aserción para comprobar nulo y probar a fondo, eliminando cualquier situación en la que se produzca una entrada nula, ya que - a.k.a errores.
  3. Para las API públicas, documente que no está permitido y deje que falle con un NPE.
+0

@downvoter ¿No hay explicación? ¿Simplemente no me gusta el corte de mi pluma? –

1

Nunca debe lanzar una excepción de tiempo de ejecución a menos que sea realmente una condición fatal para el funcionamiento del sistema, como perder parámetros de tiempo de ejecución críticos, pero incluso esto es cuestionable ya que el sistema no debería iniciarse.

¿Cuáles son las reglas del negocio? ¿Está nulo permitido para el campo? ¿No lo es?

En cualquier caso, siempre es una buena práctica CHEQUEAR por nulos en CUALQUIER parámetro pasado antes de intentar operar en ellos, por lo que no obtiene NullPointerExceptions cuando alguien le pasa datos incorrectos.

-5

Si no sabe si debe hacerlo, lo más probable es que no tenga que hacerlo.

fuentes de JDK, y el libro de Joshua Bloch, son terribles ejemplos a seguir, ya que se dirigen a un público muy diferentes. ¿Cuántos de nosotros estamos escribiendo API públicas para millones de programadores?

2

Es un aspecto desafortunado de Java que las referencias pueden ser null y no hay forma de especificar en el idioma que no lo son.

Así que, en general, sí, no invente una interpretación para null y no se meta en una situación en la que se pueda generar un NPE más tarde.

JSR305 (ahora inactivo) le permitió anotar parámetros para indicar que no se les debe dar null s.

void fn(@Nonnull String a, @Nonnull Integer b, @Nonnull Object c) { 

Verbose, pero eso es Java para usted. Hay otras librerías y comprobadores de anotaciones que hacen más o menos lo mismo, pero no son estándares.

(Nota sobre las mayúsculas:.. Cuando las palabras de camello de la carcasa de la forma "no-cosa", la standard es no capitalizar la palabra ruta a menos que sea el nombre de una clase Así nonthing y nonnull)

Las anotaciones tampoco obligan a la regla, salvo cuando se ejecuta un verificador. Puede incluir estáticamente un método para hacer la revisión:

public static <T> T nonnull(T value) { 
    if (value == null) { 
     throwNPE(); 
    } 
    return value; 
} 
private static void throwNPE() { 
    throw new NullPointerException(); 
} 

Volviendo el valor es muy útil en los constructores:

import static pkg.Check.nonnull; 

class MyClass { 
    @Nonnull private final String thing; 
    public MyClass(@Nonnull String thing) { 
     this.thing = nonnull(thing); 
    } 
    ... 
+0

Gracias Tom. Creo que las anotaciones son geniales. Y esta implementación parece mucho más limpia. –

1

Sí, métodos públicos debe frotar la entrada, especialmente si el mal de entrada podría causar problemas dentro de el código de tu métodoEs una buena idea fallar rápido; es decir, verificar lo antes posible. Java 7 añade una nueva clase Objects que hace que sea fácil de comprobar los parámetros nulos e incluir un mensaje personalizado:

public final void doSomething(String s) 
{ 
    Objects.requireNonNull(s, "The input String cannot be null"); 
    // rest of your code goes here... 
} 

Esto lanzará un NullPointerException.

Javadocs para la clase Objects: http://docs.oracle.com/javase/7/docs/api/java/util/Objects.html

Cuestiones relacionadas