Für Java-Programmierer bereitet Null Kopfschmerzen. Sie werden häufig von Null Pointer Exceptions (NPE) belästigt. Sogar der Erfinder von Java gab zu, dass dies ein großer Fehler seinerseits war. Warum bleibt Java null? Die Null gibt es schon seit einiger Zeit, und ich denke, die Java-Erfinder wussten, dass die Null mehr Ärger verursachte als die Probleme, die sie löste, aber die Null gibt es immer noch in Java.
Ich bin immer mehr überrascht, denn das Designprinzip von Java besteht darin, Dinge zu vereinfachen, weshalb keine Zeit mit Zeigern, Operatorüberladung und Mehrfachvererbungsimplementierung verschwendet wird, aber null ist genau das Gegenteil. Nun, ich kenne die Antwort auf diese Frage nicht wirklich. Was ich weiß, ist, dass wir mit Null koexistieren müssen, egal wie sehr Null von Java-Entwicklern und der Open-Source-Community kritisiert wird. Anstatt die Existenz von Null zu bereuen, sollten wir mehr über Null lernen und sicherstellen, dass Null korrekt verwendet wird.
Warum müssen Sie Null in Java lernen? Denn wenn Sie nicht auf Null achten, werden Sie in Java unter NullPointerException leiden und eine schmerzhafte Lektion lernen. Energetisches Programmieren ist eine Kunst, die Ihr Team, Ihre Kunden und Benutzer mehr schätzen werden. Meiner Erfahrung nach ist einer der Hauptgründe für Nullzeiger-Ausnahmen unzureichende Kenntnisse von Null in Java. Viele von Ihnen kennen Null bereits, aber diejenigen, die es noch nicht kennen, können etwas Altes und Neues über Null lernen. Lassen Sie uns einige wichtige Kenntnisse über Null in Java noch einmal erlernen.
Was ist Null in Java?
Wie gesagt, null ist ein sehr wichtiges Konzept in Java. Die ursprüngliche Absicht von null besteht darin, etwas Fehlendes darzustellen, beispielsweise einen fehlenden Benutzer, eine fehlende Ressource oder andere Dinge. Ein Jahr später sorgte die problematische Nullzeiger-Ausnahme jedoch für große Belästigung bei Java-Programmierern. In diesem Material lernen wir die grundlegenden Details des Null-Schlüsselworts in Java kennen und erkunden einige Techniken, um Null-Prüfungen zu minimieren und unangenehme Null-Zeiger-Ausnahmen zu vermeiden.
1) Erstens ist null ein Schlüsselwort in Java, wie public, static und final. Dabei wird die Groß-/Kleinschreibung beachtet, Sie können null nicht als Null oder NULL schreiben, der Compiler erkennt sie nicht und meldet einen Fehler.
Object obj = NULL; // Not Ok Object obj1 = null //Ok
Programmierer, die andere Sprachen verwenden, haben möglicherweise dieses Problem, aber jetzt hat die Verwendung von IDE dieses Problem trivial gemacht. Wenn Sie jetzt Code eingeben, können IDEs wie Eclipse und Netbeans diesen Fehler korrigieren. Aber wenn Sie andere Tools wie Notepad, Vim und Emacs verwenden, wird dieses Problem Ihre kostbare Zeit verschwenden.
2) So wie jeder primitive Typ einen Standardwert hat, z. B. ist der Standardwert von int 0, der Standardwert von boolean ist false, null ist der Standardwert jedes Referenztyps, nicht streng genommen, alle Objekte Der Standardwert des Typs. So wie Sie eine boolesche Variable erstellen, deren Standardwert „false“ ist, hat jede Referenzvariable in Java den Standardwert „null“. Dies gilt für alle Variablen, z. B. Mitgliedsvariablen, lokale Variablen, Instanzvariablen und statische Variablen (wenn Sie jedoch eine nicht initialisierte lokale Variable verwenden, werden Sie vom Compiler gewarnt). Um diese Tatsache zu beweisen, können Sie diese Referenzvariable beobachten, indem Sie eine Variable erstellen und dann ihren Wert ausgeben, wie im folgenden Code gezeigt:
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
Dies gilt sowohl für statische als auch für nicht statische Objekte. Wie Sie hier sehen können, habe ich myObj als statische Referenz definiert, damit ich sie direkt in der Hauptmethode verwenden kann. Beachten Sie, dass die Hauptmethode eine statische Methode ist und keine nicht statischen Variablen verwenden kann.
3) Wir möchten einige Missverständnisse klären. Es handelt sich lediglich um einen speziellen Wert. Sie können ihn auch jedem Referenztyp zuweisen. Schauen Sie sich den folgenden Code an:
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
Sie können sehen, dass null während der Kompilierung und Laufzeit in einen beliebigen Referenztyp umgewandelt wird. Alle sind machbar, und Zur Laufzeit wird keine Nullzeigerausnahme ausgelöst.
4) Null kann Referenzvariablen zugewiesen werden, Sie können jedoch Basistypvariablen wie int, double, float, boolean nicht null zuweisen. Wenn Sie das tun, gibt der Compiler einen Fehler wie diesen aus:
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
Wie Sie sehen können, wenn Sie a direkt null zuweisen Der Basistyp führt zu einem Kompilierungsfehler. Wenn Sie jedoch dem Wrapper-Klassenobjekt null zuweisen und dann das Objekt den jeweiligen Basistypen zuweisen, meldet der Compiler dies nicht, aber Sie werden zur Laufzeit auf eine Nullzeigerausnahme stoßen. Dies wird durch das automatische Unboxing in Java verursacht, was wir im nächsten Aufzählungspunkt sehen werden.
5) Jede Wrapper-Klasse, die einen Nullwert enthält, löst eine Nullzeiger-Ausnahme aus, wenn Java grundlegende Datentypen entpackt und generiert. Einige Programmierer machen den Fehler zu glauben, dass Autoboxing null in den Standardwert des jeweiligen Basistyps umwandelt, z. B. 0 für int und false für booleschen Typ, aber das ist nicht korrekt, wie unten gezeigt:
Integer iAmNull = null; int i = iAmNull; // Remember - No Compilation Error
Aber wenn Sie das obige Codefragment ausführen, werden Sie auf der Konsole sehen, dass der Hauptthread eine Nullzeigerausnahme auslöst. Viele dieser Fehler treten bei der Verwendung von HashMap- und Integer-Schlüsselwerten auf. Wenn Sie den folgenden Code ausführen, wird ein Fehler angezeigt.
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 } } }
输出:
Exception in thread "main" java.lang.NullPointerException at Test.main(Test.java:25)
这段代码看起来非常简单并且没有错误。你所做的一切是找到一个数字在数组中出现了多少次,这是Java数组中典型的寻找重复的技术。开发者首先得到以前的数值,然后再加一,最后把值放回Map里。程序员可能会以为,调用put方法时,自动装箱会自己处理好将int装箱成Interger,但是他忘记了当一个数字没有计数值的时候,HashMap的get()方法将会返回null,而不是0,因为Integer的默认值是null而不是0。当把null值传递给一个int型变量的时候自动装箱将会返回空指针异常。设想一下,如果这段代码在一个if嵌套里,没有在QA环境下运行,但是你一旦放在生产环境里,BOOM:-)
6)如果使用了带有null值的引用类型变量,instanceof操作将会返回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"); }
输出:
i
AmNull is NOT an instance of Integer
这是instanceof操作一个很重要的特性,使得对类型强制转换检查很有用
7)你可能知道不能调用非静态方法来使用一个值为null的引用类型变量。它将会抛出空指针异常,但是你可能不知道,你可以使用静态方法来使用一个值为null的引用类型变量。因为静态方法使用静态绑定,不会抛出空指针异常。下面是一个例子:
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"); }
输出:
I am static method, can be called by null reference Exception in thread "main" java.lang.NullPointerException at Testing.main(Testing.java:11)
8)你可以将null传递给方法使用,这时方法可以接收任何引用类型,例如public void print(Object obj)可以这样调用print(null)。从编译角度来看这是可以的,但结果完全取决于方法。Null安全的方法,如在这个例子中的print方法,不会抛出空指针异常,只是优雅的退出。如果业务逻辑允许的话,推荐使用null安全的方法。
9)你可以使用==或者!=操作来比较null值,但是不能使用其他算法或者逻辑操作,例如小于或者大于。跟SQL不一样,在Java中null==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){ } } }
输出:
null == null is true in Java
这是关于Java中null的全部。通过Java编程的一些经验和使用简单的技巧来避免空指针异常,你可以使你的代码变得null安全。因为null经常作为空或者未初始化的值,它是困惑的源头。对于方法而言,记录下null作为参数时方法有什么样的行为也是非常重要的。总而言之,记住,null是任何一个引用类型变量的默认值,在java中你不能使用null引用来调用任何的instance方法或者instance变量。