Para los programadores de Java, null es un dolor de cabeza. A menudo lo acosan las excepciones de puntero nulo (NPE). Incluso el inventor de Java admitió que se trataba de un gran error de su parte. ¿Por qué Java se mantiene nulo? El nulo ha existido por un tiempo, y creo que los inventores de Java sabían que el nulo causaba más problemas que los problemas que resolvía, pero el nulo todavía está en Java.
Estoy cada vez más sorprendido, porque el principio de diseño de Java es simplificar las cosas, por eso no se pierde tiempo en punteros, sobrecarga de operadores y la implementación de herencia múltiple es todo lo contrario. Bueno, realmente no sé la respuesta a esta pregunta, lo que sí sé es que no importa cuán criticado sea null por los desarrolladores de Java y la comunidad de código abierto, tenemos que coexistir con null. En lugar de lamentar la existencia de null, deberíamos aprender mejor sobre null y asegurarnos de que se use correctamente.
¿Por qué necesitas aprender nulo en Java? Porque si no prestas atención a nulo, Java te hará sufrir NullPointerException y aprenderás una lección dolorosa. La programación energética es un arte que tu equipo, clientes y usuarios apreciarán más. En mi experiencia, una de las principales razones de las excepciones de puntero nulo es el conocimiento insuficiente de nulo en Java. Muchos de ustedes ya están familiarizados con null, pero aquellos que no lo están, pueden aprender algo antiguo y nuevo sobre null. Volvamos a aprender algunos conocimientos importantes sobre nulos en Java.
¿Qué es nulo en Java?
Como dije, nulo es un concepto muy importante en Java. La intención original de null es representar algo que falta, como un usuario, un recurso u otras cosas faltantes. Sin embargo, un año después, la problemática excepción del puntero nulo provocó mucho acoso a los programadores de Java. En este material, aprenderemos los detalles básicos de la palabra clave nula en Java y exploraremos algunas técnicas para minimizar las comprobaciones de nulos y cómo evitar desagradables excepciones de puntero nulo.
1) En primer lugar, nulo es una palabra clave en Java, como pública, estática y final. Distingue entre mayúsculas y minúsculas, no puede escribir nulo como Null o NULL, el compilador no los reconocerá e informará un error.
Copie el código de código de la siguiente manera:
Objeto obj = NULL // No está bien
Objeto obj1 = nulo //Aceptar
Los programadores que utilizan otros lenguajes pueden tener este problema, pero ahora el uso de IDE ha hecho que este problema sea trivial. Ahora, cuando escribe código, IDE como Eclipse y Netbeans pueden corregir este error. Pero al utilizar otras herramientas como el Bloc de notas, Vim y Emacs, este problema le hará perder su valioso tiempo.
2) Al igual que cada tipo primitivo tiene un valor predeterminado, por ejemplo, el valor predeterminado de int es 0, el valor predeterminado de booleano es falso y nulo es el valor predeterminado de cualquier tipo de referencia. Estrictamente hablando, es el valor predeterminado. de todo tipo de objetos. Al igual que crea una variable booleana que tiene falso como valor predeterminado, cualquier variable de referencia en Java tiene nulo como valor predeterminado. Esto es cierto para todas las variables, como variables miembro, variables locales, variables de instancia, variables estáticas (pero cuando usa una variable local no inicializada, el compilador le advertirá). Para demostrar este hecho, puede observar esta variable de referencia creando una variable y luego imprimiendo su valor, como se muestra en el siguiente código:
Copie el código de código de la siguiente manera:
Objeto estático privado myObj;
principal vacío estático público (String args []) {
System.out.println("¿Cuál es el valor de myObjc: " + myObj);
}
¿Cuál es el valor de myObjc: nulo?
Esto es válido tanto para objetos estáticos como para no estáticos. Como puede ver aquí, definí myObj como una referencia estática para poder usarlo directamente en el método principal. Tenga en cuenta que el método principal es un método estático y no puede utilizar variables no estáticas.
3) Queremos aclarar algunos malentendidos. Null no es un objeto ni un tipo. Es solo un valor especial. Puede asignarlo a cualquier tipo de referencia. También puede convertir null a cualquier tipo.
Copie el código de código de la siguiente manera:
String str = null; // null se puede asignar a String
Integer itr = null; // también puedes asignar null a Integer;
Double dbl = null; // null también se puede asignar a Double
String myStr = (String) null; // null se puede convertir a String
Integer myItr = (Integer) null // también se puede convertir a Integer
Double myDbl = (Double) null; // sí, es posible, no hay error
Puede ver que es posible convertir nulo a cualquier tipo de referencia en tiempo de compilación y ejecución, y no generará una excepción de puntero nulo en tiempo de ejecución.
4) Se puede asignar nulo a variables de referencia, pero no se puede asignar nulo a variables de tipo básico, como int, double, float y boolean. Si haces eso, el compilador arrojará un error como este:
Copie el código de código de la siguiente manera:
int i = null; // el tipo no coincide: no se puede convertir de nulo a int
short s = null; // el tipo no coincide: no se puede convertir de nulo a corto
byte b = null: // el tipo no coincide: no se puede convertir de nulo a byte
double d = null; //tipo no coincidente: no se puede convertir de nulo a doble
Entero itr = null; // esto está bien
int j = itr; // esto también está bien, pero NullPointerException en tiempo de ejecución
Como puede ver, cuando asigna nulo directamente a un tipo primitivo, se produce un error de compilación. Pero si asigna nulo al objeto de clase contenedora y luego asigna el objeto a los tipos básicos respectivos, el compilador no lo informará, pero encontrará una excepción de puntero nulo en tiempo de ejecución. Esto se debe al unboxing automático en Java, que veremos en el siguiente punto.
5) Cualquier clase contenedora que contenga un valor nulo generará una excepción de puntero nulo cuando Java desempaquete y genere tipos de datos básicos. Algunos programadores cometen el error de pensar que el autoboxing convertirá null al valor predeterminado del tipo básico respectivo, como 0 para int y false para tipo booleano, pero eso no es correcto, como se muestra a continuación:
Copie el código de código de la siguiente manera:
Entero iAmNull = nulo;
int i = iAmNull; // Recuerde: no hay error de compilación
Pero cuando ejecuta el fragmento de código anterior, verá en la consola que el hilo principal genera una excepción de puntero nulo. Muchos de estos errores ocurren cuando se utilizan valores de clave HashMap e Integer. Aparecerá un error cuando ejecute el siguiente código.
Copie el código de código de la siguiente manera:
importar java.util.HashMap;
importar java.util.Map;
/**
* Un ejemplo de Autoboxing y NullPointerExcpetion
*
* @autor WINDOWS 8
*/
Prueba de clase pública {
public static void main (String args []) lanza InterruptedException {
Número de mapaAndCount = new HashMap<>();
int[] números = {3, 5, 7,9, 11, 13, 17, 19, 2, 3, 5, 33, 12, 5};
para(int i: números){
int recuento = numeroAndCount.get(i);
numberAndCount.put(i, count++); // NullPointerException aquí
}
}
}
Producción:
Copie el código de código de la siguiente manera:
Excepción en el hilo "principal" java.lang.NullPointerException
en Prueba.main(Test.java:25)
Este código parece muy simple y libre de errores. Todo lo que hay que hacer es encontrar cuántas veces aparece un número en una matriz, que es la técnica típica para encontrar duplicados en matrices de Java. El desarrollador primero obtiene el valor anterior, luego agrega uno y finalmente vuelve a colocar el valor en el mapa. El programador puede pensar que al llamar al método put, el boxeo automático manejará el boxeo de int en Interger, pero olvida que cuando un número no tiene un valor de conteo, el método get () de HashMap devolverá nulo y no 0. , porque el valor predeterminado de Integer es nulo, no 0. Autoboxing devolverá una NullPointerException al pasar un valor nulo a una variable int. Imagínese si este código estuviera dentro de un nido if y no se ejecutara en un entorno de control de calidad, pero una vez que lo coloque en un entorno de producción, BOOM :-)
6) Si se utiliza una variable de tipo de referencia con un valor nulo, la operación instancia de devolverá falso:
Copie el código de código de la siguiente manera:
Entero iAmNull = nulo;
if(soyNull instancia de Integer){
System.out.println("iAmNull es una instancia de Integer");
}demás{
System.out.println("iAmNull NO es una instancia de Integer");
}
Producción:
Copie el código de código de la siguiente manera:
i
AmNull NO es una instancia de Integer
Esta es una característica muy importante de la operación de instancia, lo que la hace útil para comprobaciones de conversión de tipos.
7) Quizás sepa que no puede llamar a un método no estático para usar una variable de tipo de referencia con un valor nulo. Lanzará una excepción de puntero nulo, pero es posible que no sepa que puede usar métodos estáticos para usar una variable de tipo de referencia con un valor nulo. Debido a que los métodos estáticos utilizan enlaces estáticos, no se generarán excepciones de puntero nulo. Aquí hay un ejemplo:
Copie el código de código de la siguiente manera:
prueba de clase pública {
principal vacío estático público (String args []) {
Probando miObjeto = nulo;
myObject.iAmStaticMethod();
myObject.iAmNonStaticMethod();
}
vacío estático privado iAmStaticMethod(){
System.out.println("Soy un método estático, se puede llamar mediante referencia nula");
}
vacío privado iAmNonStaticMethod(){
System.out.println("Soy un método NO estático, no tengas citas para llamarme como nulo");
}
Producción:
Copie el código de código de la siguiente manera:
Soy un método estático, se puede llamar mediante referencia nula.
Excepción en el hilo "principal" java.lang.NullPointerException
en Testing.main (Testing.java:11)
8) Puede pasar nulo al método, y el método puede recibir cualquier tipo de referencia. Por ejemplo, public void print(Object obj) puede llamar a print(null) de esta manera. Esto está bien desde la perspectiva de la compilación, pero el resultado depende completamente del método. Los métodos seguros para nulos, como el método de impresión en este ejemplo, no lanzan una excepción NullPointerException y simplemente salen con gracia. Si la lógica empresarial lo permite, se recomienda utilizar métodos seguros para nulos.
9) Puede usar operaciones == o != para comparar valores nulos, pero no puede usar otros algoritmos u operaciones lógicas, como menor o mayor que. A diferencia de SQL, null==null devolverá verdadero en Java, como se muestra a continuación:
Copie el código de código de la siguiente manera:
Prueba de clase pública {
public static void main (String args []) lanza InterruptedException {
Cadena abc = nula;
Cadena cde = nulo;
si(abc == cde){
System.out.println("null == null es verdadero en Java");
}
si(nulo!=nulo){
System.out.println("null!= null es falso en Java");
}
// verificación nula clásica
si(abc==nulo){
// hacer algo
}
// no está bien, error en el tiempo de compilación
si(abc > nulo){
}
}
}
Producción:
Copie el código de código de la siguiente manera:
nulo == nulo es verdadero en Java
Se trata de nulo en Java. Con algo de experiencia en programación Java y usando trucos simples para evitar excepciones de puntero nulo, puede hacer que su código sea seguro para nulos. Dado que nulo se utiliza a menudo como un valor vacío o no inicializado, es fuente de confusión. Para los métodos, también es muy importante registrar cómo se comporta el método cuando se utiliza nulo como parámetro. Considerándolo todo, recuerde que nulo es el valor predeterminado de cualquier variable de tipo de referencia. No puede usar referencias nulas para llamar a ningún método de instancia o variable de instancia en Java.