为什么要学习 Java 中的 null ?
因为如果你不注意 null,你可以肯定 Java 会让你遭受可怕的痛苦java.lang.NullPointerException
,你会吸取教训,但你会走上一条艰难的道路。编写抗崩溃代码是一门艺术,您的团队、客户和用户都会欣赏它。根据我的经验,主要原因之一NullPointerException
是缺乏对 Java 中 null 的了解。你们中的许多人已经熟悉 null,其余的人将能够了解有关 null 关键字的一些新旧知识。让我们回顾或学习有关 Java 中 null 的一些重要知识。
Java中什么是null
正如我所说,null 是 Java 中一个非常非常重要的概念。它最初被发明是为了指示某些东西的缺失,例如用户、资源或其他任何东西的缺失,但一直让许多 Java 程序员感到困惑null pointer exception
。在本教程中,我们将了解有关 Java 中 null 关键字的基本事实,并学习一些避免出现问题并尽量null pointer exceptions
减少 null 检查的技巧。
-
首先,null 是 Java 中的一个关键字,就像
public
,static
或final
。大小写敏感,不能将 null 写为 Null 或 NULL,编译器将无法识别并抛出错误。Object obj = NULL; // Not Ok Object obj1 = null //Ok
通常,从其他编程语言转过来的程序员会遇到这个问题,但是当使用现代 IDE 时,这个问题就变得微不足道了。如今,Eclipse 或 NetBeans 等 IDE 可以在您键入时修复此错误,但在记事本、Vim 和 Emacs 时代,这是一个常见问题,可能会占用大量宝贵时间。
-
Так же, 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)
这段代码看起来非常简单而且无害。您只需计算一个数字在数组中出现的次数,这是查找重复项的经典技术。开发人员获取之前计数的数量,将其加一并将其插回到 中
Map
。他可能认为自动装箱会处理Integer
到 的转换int
,就像调用该方法时所做的那样put()
,但他忘记了,如果尚未计算数字,该方法get()
将返回HashMap
null,而不是零,因为默认值is Integer 这是 null,而不是 0,null pointer exception
当尝试将 Integer 转换为变量时,自动装箱将会抛出异常int
。 -
instanceof
如果将任何值为 null 的引用变量或 null 本身指定为参数,则该运算符将返回 false。例子: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
这是该运算符的一个重要属性
instanceof
,使其对于测试类型转换很有用。 -
您知道不能对空引用变量调用非静态方法,它会调用
NullPointerException
,但您可能不知道可以对空引用变量调用静态方法。因为 静态方法使用静态绑定,它们不会丢弃NullPointerException
。这是一个例子: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)
-
您可以将 null 作为参数传递给接受任何引用类型的方法,例如:
public void print(Object obj)
可以这样称呼
print(null)
从编译器的角度来看,这是正常的,但后续行为完全取决于该方法。null 安全方法不会抛出异常
NullPointerException
,而只会优雅地退出。如果业务逻辑允许,建议编写空安全方法。 -
您可以使用
==
(等于)和!=
(不等于)运算符来比较 null,但不能将其与其他算术或逻辑运算符(例如,<
小于)或>
(大于)一起使用。与 SQL 不同,Javanull == null
将返回 true,如下所示: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
,您可以使您的代码安全。因为 null 可以被视为空值或未初始化的值,这通常会造成混乱,这就是为什么在输入 null 值时记录方法的行为很重要。永远记住,null 是引用变量的默认值,并且您不能在 Java 中使用 null 引用来调用实例方法或访问实例变量。
GO TO FULL VERSION