Why should you learn about null in Java?
Because if you don't pay attention to null, you can be sure that Java will make you suffer in a terrible wayjava.lang.NullPointerException
and you will learn your lesson, but you will go the hard way. Writing crash-resistant code is an art and your team, customers and users will appreciate it. In my experience, one of the main reasons NullPointerException
is lack of knowledge about null in Java. Many of you are already familiar with null, the rest of you will be able to learn some old and new things about the null keyword. Let's review or learn some important things about null in Java.
What is null in Java
As I said, null is a very, very important concept in Java. It was originally invented to indicate the absence of something, such as the absence of a user, a resource, or whatever, but has been puzzling Java programmers with a lot ofnull pointer exception
. In this tutorial, we'll learn the basic facts about the null keyword in Java, and learn some tricks to avoid trouble with null pointer exceptions
and minimize null checks.
-
First things first, null is a keyword in Java, just like
public
,static
orfinal
. Case is sensitive, you cannot write null as Null or NULL, the compiler will not recognize it and an error will be thrown.Object obj = NULL; // Not Ok Object obj1 = null //Ok
This is often encountered by programmers who have switched from other programming languages, but when using modern IDEs, the problem becomes insignificant. These days, IDEs like Eclipse or NetBeans can fix this error while you type, but in the era of Notepad, Vim and Emacs, this was a common problem that could eat up a lot of valuable time.
-
Так же, How каждый примитив имеет meaning по умолчанию, например, у
int
это 0, у boolean это false, null это meaning по умолчанию любых ссылочных типов, проще говоря, для всех an objectов. Так же, How при создании логической переменной ее meaning по умолчанию равно false, так и любые ссылочные переменные в Java по умолчанию будут равны null. Это истинно для всех типов переменных: переменной-члена or локальной переменной, переменной экземпляра or статической переменной, кроме того, компилятор будет ругаться, если Вы используете локальную переменную не проинициализировав ее.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
Это истинно How для статических, так и для не статических an objectов, How Вы можете видеть здесь, я сделал
myObj
статической ссылкой, так что я могу использовать ее непосредственно в методеmain
, который является статическим методом и не позволяет обращаться к не статическим переменным изнутри. -
Несмотря на распространенное заблуждение, null это не an object (
Object
) и ни тип. Это просто специальное meaning, которое может быть назначено любому ссылочному типу, и Вы можете привести null к любому типу, How показано ниже: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 к любому ссылочному типу пройдет успешно How во время компиляции, так и во время выполнения программы. В отличии от того, что многие из Вас возможно подумали, это не приведет к выбрасыванию
NullPointerException
. -
null может быть назначен только ссылочному типу, Вы не можете назначить null примитивной переменной вроде
int
,double
,float
orboolean
. Компилятор выразит Вам свое недовольство если Вы сделаете How показано ниже: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 an objectу класса-обертки, а затем присвоить этот an object соответствующему примитивному типу, компилятор не отреагирует, но мы будем вознаграждены
null pointer exception
во время выполнения. Это происходит из-за авто упаковки (autoboxing
) в Java, и мы еще встретимся с ним в следующем пункте. -
Любой класс-обертка со meaningм null будет выбрасывать
java.lang.NullPointerException
когда Java распакует(unbox
) его в примитивную переменную. Некоторые программисты делают ошибку допуская, что авто упаковка(autoboxing
) позаботится о конвертации null в meaning по умолчанию для соответствующего примитивного типа, например, 0 дляint
, false дляboolean
и т.д., но это не верно, в чем можно убедиться ниже:Integer iAmNull = null; int i = iAmNull; // Remember - No Compilation Error
Но, когда Вы запустите данный фрагмент codeа, в консоли Вы увидите
Exception in thread "main" java.lang.NullPointerException
Это часто происходит при работе с
HashMap
иInteger key
. Выполнение codeа, показанного ниже прервется, How только Вы его запустите.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)
This code looks very simple and harmless. You simply count how many times a number appears in an array, a classic technique for finding duplicates. The developer takes the previous counted quantity, increases it by one and inserts it back into
Map
. He might think that auto-boxing will take care of the conversionInteger
toint
, as it does when the method is calledput()
, but he forgets that if the number has not yet been counted, the methodget()
will returnHashMap
null, not zero, because the default value is Integer this is null, not 0, and auto-boxing will thrownull pointer exception
when trying to convert an Integer to a variableint
. -
The operator
instanceof
will return false if any reference variable with the value null or null itself is specified as a parameter. Example: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
This is an important property of the operator
instanceof
that makes it useful for testing type casts. -
You know that you can't call a non-static method on a null reference variable, it will call
NullPointerException
, but you may not know that you can call a static method on a null reference variable. Because static methods use static binding, they don't throw awayNullPointerException
. Here's an example: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)
-
You can pass null as a parameter to a method that accepts any reference type, for example:
public void print(Object obj)
can be called like
print(null)
This is normal from the compiler's point of view, but the subsequent behavior is entirely dependent on the method. A null-safe method will not throw
NullPointerException
, but will simply exit gracefully. If business logic allows, it is recommended to write null-safe methods. -
You can compare null using the
==
(equal) and!=
(not equal) operators, but you cannot use it with other arithmetic or logical operators like<
(less than) or>
(greater than). Unlike SQL, Javanull == null
will return true as shown below: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
, you can make your code safe. Because null can be treated as an empty or uninitialized value, this is often a source of confusion, which is why it is important to document the behavior of a method when a null value is input. Always remember, null is the default value of reference variables, and you cannot call instance methods or access instance variables using a null reference in Java.
GO TO FULL VERSION