¿Por qué debería aprender sobre nulo en Java?
Porque si no le prestas atención a null, puedes estar seguro de que Java te hará sufrir terriblementejava.lang.NullPointerException
y aprenderás la lección, pero irás por el camino más difícil. Escribir código resistente a fallas es un arte y su equipo, clientes y usuarios lo apreciarán. En mi experiencia, una de las razones principales NullPointerException
es la falta de conocimiento sobre nulos en Java. Muchos de ustedes ya están familiarizados con null, el resto podrá aprender algunas cosas nuevas y antiguas sobre la palabra clave null. Repasemos o aprendamos algunas cosas importantes sobre nulo en Java.
¿Qué es nulo en Java?
Como dije, nulo es un concepto muy, muy importante en Java. Originalmente se inventó para indicar la ausencia de algo, como la ausencia de un usuario, un recurso o lo que sea, pero ha estado desconcertando a los programadores de Java con muchosnull pointer exception
. En este tutorial, aprenderemos los datos básicos sobre la palabra clave nula en Java y aprenderemos algunos trucos para evitar problemas null pointer exceptions
y minimizar las comprobaciones de nulos.
-
Lo primero es lo primero, nulo es una palabra clave en Java, al igual que
public
o . Las mayúsculas y minúsculas son sensibles, no puede escribir nulo como Nulo o NULL, el compilador no lo reconocerá y se generará un error.static
final
Object obj = NULL; // Not Ok Object obj1 = null //Ok
Esto lo encuentran a menudo los programadores que han cambiado de otros lenguajes de programación, pero cuando utilizan IDE modernos, el problema se vuelve insignificante. Hoy en día, los IDE como Eclipse o NetBeans pueden corregir este error mientras escribes, pero en la era del Bloc de notas, Vim y Emacs, este era un problema común que podía consumir mucho tiempo valioso.
-
Так же, Cómo каждый примитив имеет significado по умолчанию, например, у
int
это 0, у boolean это false, null это significado по умолчанию любых ссылочных типов, проще говоря, для всех un objetoов. Так же, Cómo при создании логической переменной ее significado по умолчанию равно false, так и любые ссылочные переменные в Java по умолчанию будут равны null. Это истинно для всех типов переменных: переменной-члена o локальной переменной, переменной экземпляра o статической переменной, кроме того, компилятор будет ругаться, если Вы используете локальную переменную не проинициализировав ее.private static Object myObj; public static void main(String args[]){ System.out.println("What is value of myObjc : " + myObj); } What is value of myObjc : null
Это истинно Cómo для статических, так и для не статических un objetoов, Cómo Вы можете видеть здесь, я сделал
myObj
статической ссылкой, так что я могу использовать ее непосредственно в методеmain
, который является статическим методом и не позволяет обращаться к не статическим переменным изнутри. -
Несмотря на распространенное заблуждение, null это не un objeto (
Object
) и ни тип. Это просто специальное significado, которое может быть назначено любому ссылочному типу, и Вы можете привести null к любому типу, Cómo показано ниже:String str = null; // null can be assigned to String Integer itr = null; // you can assign null to Integer also Double dbl = null; // null can also be assigned to Double String myStr = (String) null; // null can be type cast to String Integer myItr = (Integer) null; // it can also be type casted to Integer Double myDbl = (Double) null; // yes it's possible, no error
Как Вы можете видеть, приведение null к любому ссылочному типу пройдет успешно Cómo во время компиляции, так и во время выполнения программы. В отличии от того, что многие из Вас возможно подумали, это не приведет к выбрасыванию
NullPointerException
. -
null может быть назначен только ссылочному типу, Вы не можете назначить null примитивной переменной вроде
int
,double
,float
oboolean
. Компилятор выразит Вам свое недовольство если Вы сделаете Cómo показано ниже:int i = null; // type mismatch : cannot convert from null to int short s = null; // type mismatch : cannot convert from null to short byte b = null: // type mismatch : cannot convert from null to byte double d = null; //type mismatch : cannot convert from null to double Integer itr = null; // this is ok int j = itr; // this is also ok, but NullPointerException at runtime
Как Вы можете видеть, когда мы непосредственно присваиваем null примитиву, то получаем ошибку процесса компиляции, но, если присвоить null un objetoу класса-обертки, а затем присвоить этот un objeto соответствующему примитивному типу, компилятор не отреагирует, но мы будем вознаграждены
null pointer exception
во время выполнения. Это происходит из-за авто упаковки (autoboxing
) в Java, и мы еще встретимся с ним в следующем пункте. -
Любой класс-обертка со significadoм null будет выбрасывать
java.lang.NullPointerException
когда Java распакует(unbox
) его в примитивную переменную. Некоторые программисты делают ошибку допуская, что авто упаковка(autoboxing
) позаботится о конвертации null в significado по умолчанию для соответствующего примитивного типа, например, 0 дляint
, false дляboolean
и т.д., но это не верно, в чем можно убедиться ниже:Integer iAmNull = null; int i = iAmNull; // Remember - No Compilation Error
Но, когда Вы запустите данный фрагмент códigoа, в консоли Вы увидите
Exception in thread "main" java.lang.NullPointerException
Это часто происходит при работе с
HashMap
иInteger key
. Выполнение códigoа, показанного ниже прервется, Cómo только Вы его запустите.import java.util.HashMap; import java.util.Map; /** * An example of Autoboxing and NullPointerExcpetion * * @author WINDOWS 8 */ public class Test { public static void main(String args[]) throws InterruptedException { Map numberAndCount = new HashMap<>(); int[] numbers = {3, 5, 7,9, 11, 13, 17, 19, 2, 3, 5, 33, 12, 5}; for(int i : numbers){ int count = numberAndCount.get(i); numberAndCount.put(i, count++); // NullPointerException here } } }
Output: Exception in thread "main" java.lang.NullPointerException at Test.main(Test.java:25)
Este código parece muy simple e inofensivo. Simplemente cuenta cuántas veces aparece un número en una matriz, una técnica clásica para encontrar duplicados. El desarrollador toma la cantidad contada anteriormente, la aumenta en uno y la vuelve a insertar en
Map
. Podría pensar que el auto-boxing se encargará de la conversiónInteger
aint
, como lo hace cuando se llama al métodoput()
, pero olvida que si el número aún no ha sido contado, el métodoget()
devolveráHashMap
nulo, no cero, porque el valor predeterminado es un número entero, esto es nulo, no 0, y el boxeo automático se produciránull pointer exception
al intentar convertir un número entero en una variableint
. -
El operador
instanceof
devolverá falso si se especifica como parámetro cualquier variable de referencia con el valor nulo o nulo. Ejemplo:Integer iAmNull = null; if(iAmNull instanceof Integer){ System.out.println("iAmNull is instance of Integer"); }else{ System.out.println("iAmNull is NOT an instance of Integer"); }
Output : iAmNull is NOT an instance of Integer
Esta es una propiedad importante del operador
instanceof
que lo hace útil para probar conversiones de tipos. -
Usted sabe que no puede llamar a un método no estático en una variable de referencia nula, llamará
NullPointerException
, pero es posible que no sepa que puede llamar a un método estático en una variable de referencia nula. Porque Los métodos estáticos utilizan enlaces estáticos, no se desechanNullPointerException
. He aquí un ejemplo:public class Testing { public static void main(String args[]){ Testing myObject = null; myObject.iAmStaticMethod(); myObject.iAmNonStaticMethod(); } private static void iAmStaticMethod(){ System.out.println("I am static method, can be called by null reference"); } private void iAmNonStaticMethod(){ System.out.println("I am NON static method, don't date to call me by null"); } }
Output: I am static method, can be called by null reference Exception in thread "main" java.lang.NullPointerException at Testing.main(Testing.java:11)
-
Puede pasar null como parámetro a un método que acepte cualquier tipo de referencia, por ejemplo:
public void print(Object obj)
se puede llamar como
print(null)
Esto es normal desde el punto de vista del compilador, pero el comportamiento posterior depende completamente del método. Un método seguro para nulos no arrojará
NullPointerException
, sino que simplemente saldrá con gracia. Si la lógica empresarial lo permite, se recomienda escribir métodos seguros para nulos. -
Puede comparar nulos usando los operadores
==
(igual) y!=
(no igual), pero no puede usarlo con otros operadores aritméticos o lógicos como<
(menor que) o>
(mayor que). A diferencia de SQL, Javanull == null
devolverá verdadero como se muestra a continuación:public class Test { public static void main(String args[]) throws InterruptedException { String abc = null; String cde = null; if(abc == cde){ System.out.println("null == null is true in Java"); } if(null != null){ System.out.println("null != null is false in Java"); } // classical null check if(abc == null){ // do something } // not ok, compile time error if(abc > null){ } } }
Output: null == null is true in Java
NullPointerException
, podrá hacer que su código sea seguro. Porque null puede tratarse como un valor vacío o no inicializado, lo que suele ser fuente de confusión, por lo que es importante documentar el comportamiento de un método cuando se ingresa un valor nulo. Recuerde siempre que nulo es el valor predeterminado de las variables de referencia y no puede llamar a métodos de instancia ni acceder a variables de instancia utilizando una referencia nula en Java.
GO TO FULL VERSION