usar new icon example codigo borderfactory java null guava preconditions

example - new icon java



Cuál es el punto de Guava checkNotNull (3)

Soy bastante nuevo en Guava (seamos honestos, no soy "bastante nuevo", soy un completo novato en ese tema) y entonces decidí revisar algunos documentos y me sorprendí al leer esto:

com.google.common.base.Preconditions.checkNotNull(...)

No entiendo el objetivo de este método. Esto significa que en lugar de hacer:

myObject.getAnything();

(que podría causar una NullPointerException si myObject es nulo)

Debo usar

checkNotNull(myObject).getAnything();

que lanzará una NullPointerException si myObject es nulo y devuelve myObject si no es nulo.

Estoy desconcertado y esta podría ser la pregunta más estúpida de la historia pero ...

¿Cual es el punto de esto? Esas dos líneas hacen exactamente lo mismo que para los resultados dados las situaciones que se me ocurren.

Ni siquiera creo que este último sea más legible.

Así que debo estar perdiendo algo. ¿Qué es?


myObject.getAnything(); (que podría causar una NullPointerException si myObject es nulo)

No ... arrojará NPE cada vez que myObject == null . En Java, no hay posibilidad de invocar un método con receptor null (una excepción teórica son los métodos estáticos, pero pueden y deben invocarse siempre sin ningún objeto).

Debería usar checkNotNull(myObject).getAnything();

No, no deberías. Esto sería bastante redundante ( Actualización ).

Deberías usar checkNotNull para fallar rápido . Sin él, puede pasar un null ilegal a otro método, que lo pasa más allá, y así sucesivamente, donde finalmente falla. Entonces puede necesitar un poco de buena suerte para descubrir que en realidad el primer método debería haber rechazado el null .

La respuesta de yshavit menciona un punto importante: pasar un valor ilegal es malo, pero almacenarlo y pasarlo más tarde es aún peor.

Actualizar

Actualmente,

checkNotNull(myObject).getAnything()

también tiene sentido, ya que claramente expresas tu intención de no aceptar ningún nulo. Sin él, alguien podría pensar que olvidó el cheque y lo convirtió en algo así como

myObject != null ? myObject.getAnything() : somethingElse

OTOH, no creo que el cheque valga la pena la verbosidad. En un lenguaje mejor , el sistema de tipo consideraría la capacidad de nulidad y nos daría algo de azúcar semántica como

myObject!!.getAnything() // checkNotNull myObject?.getAnything() // safe call else null myObject?.getAnything() ?: somethingElse // safe call else somethingElse

para myObject myObject , mientras que la sintaxis de punto estándar solo se permitiría cuando se sepa que myObject es nulo.


He leído este hilo hace unos minutos. Sin embargo, estaba confundido por qué deberíamos usar checkNotNull . Luego mire la documentación de la clase Precondition de Guava y obtuve lo que esperaba. El uso excesivo de checkNotNull degradará el rendimiento definitivamente.

Mi pensamiento es que el método checkNotNull vale la pena para la validación de datos que proviene del usuario directamente o de la API final para la interacción del usuario. No debe usarse en todos y cada uno de los métodos de la API interna porque al usarla no se puede detener la excepción, sino que se puede corregir la API interna para evitar Excepción.

De acuerdo con DOC: Link

Usando checkNotNull:

public static double sqrt(double value) { Preconditions.checkArgument(value >= 0.0, "negative value: %s", value); // calculate the square root }

Advertencia sobre el rendimiento

El objetivo de esta clase es mejorar la legibilidad del código, pero en algunas circunstancias esto puede tener un costo de rendimiento significativo. Recuerde que los valores de los parámetros para la construcción de mensajes deben ser calculados con entusiasmo, y también pueden ocurrir la creación de autoboxing y varargs array, incluso cuando la verificación de precondición tenga éxito (como casi siempre debería ocurrir en producción). En algunas circunstancias, estos ciclos y asignaciones de CPU desperdiciados pueden sumarse a un problema real. Las verificaciones de condiciones previas sensibles al rendimiento siempre se pueden convertir a la forma habitual:

if (value < 0.0) { throw new IllegalArgumentException("negative value: " + value); }


La idea es fallar rápido. Por ejemplo, considera esta clase tonta:

public class Foo { private final String s; public Foo(String s) { this.s = s; } public int getStringLength() { return s.length(); } }

Digamos que no quiere permitir valores nulos para s . (o si no, getStringLength lanzará un NPE). Con la clase tal como está, cuando atrapas ese null , es demasiado tarde, es muy difícil saber quién lo puso allí. El culpable bien podría estar en una clase totalmente diferente, y esa instancia Foo podría haber sido construida hace mucho tiempo. Ahora tiene que peinar su base de código para descubrir quién podría haber puesto un valor null allí.

En cambio, imagina este constructor:

public Foo(String s) { this.s = checkNotNull(s); }

Ahora, si alguien pone un null allí, lo descubrirá de inmediato , y tendrá el rastro de la pila apuntando exactamente a la llamada que salió mal.

En otro momento, esto puede ser útil si desea verificar los argumentos antes de tomar medidas que pueden modificar el estado. Por ejemplo, considere esta clase que calcula el promedio de todas las longitudes de cadena que obtiene:

public class StringLengthAverager { private int stringsSeen; private int totalLengthSeen; public void accept(String s) { stringsSeen++; totalLengthSeen += s.length(); } public double getAverageLength() { return ((double)totalLengthSeen) / stringsSeen; } }

Llamar accept(null) hará que se genere un NPE, pero no antes de que se haya incrementado stringsSeen . Esto puede no ser lo que quieres; como usuario de la clase, puedo esperar que si no acepta nulos, entonces su estado no se modifique si pasa un nulo (en otras palabras: la llamada debe fallar, pero no debe invalidar el objeto). Obviamente, en este ejemplo también puede solucionarlo obteniendo s.length() antes de incrementar stringsSeen , pero puede ver cómo, para un método más largo y más complicado, puede ser útil verificar primero que todos sus argumentos sean válidos, y solo entonces modifique el estado:

public void accept(String s) { checkNotNull(s); // that is, s != null is a precondition of the method stringsSeen++; totalLengthSeen += s.length(); }