Heim  >  Artikel  >  Java  >  9 Dinge, die Sie über Null in Java wissen sollten

9 Dinge, die Sie über Null in Java wissen sollten

伊谢尔伦
伊谢尔伦Original
2016-11-26 09:38:271180Durchsuche

Für Java-Programmierer bereitet Null Kopfschmerzen. Sie werden oft 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.

9 Dinge, die Sie über Null in Java wissen sollten


Ich bin immer mehr überrascht, denn das Designprinzip von Java besteht darin, Dinge zu vereinfachen, deshalb wird keine Zeit verschwendet Zeiger, Operatorüberladung, der Grund für die Implementierung der Mehrfachvererbung, 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 des Null-Designs 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) Zunächst einmal 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) Genauso wie jeder primitive Typ einen Standardwert hat, z. B. ist der Standardwert von int 0, der Standardwert von boolean ist false und 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 für statische und nicht statische Objekte Alle sind richtig. 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. Null ist weder ein Objekt noch ein Typ. Sie können ihn 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 es möglich ist, während der Kompilierung und Laufzeit Null in einen beliebigen Referenztyp umzuwandeln, und dass zur Laufzeit kein Nullzeiger ausgelöst wird.

4) Null kann Referenzvariablen zugewiesen werden, Sie können jedoch Basistypvariablen wie int, double, float, boolean nicht null zuweisen. Wenn Sie das tun, meldet der Compiler einen Fehler wie diesen:

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, tritt ein Kompilierungsfehler auf, wenn Sie null direkt einem Basistyp zuweisen. 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, das wir im nächsten Aufzählungspunkt sehen werden.

  5) 任何含有null值的包装类在Java拆箱生成基本数据类型时候都会抛出一个空指针异常。一些程序员犯这样的错误,他们认为自动装箱会将null转换成各自基本类型的默认值,例如对于int转换成0,布尔类型转换成false,但是那是不正确的,如下面所示:

Integer iAmNull = null;
int i = iAmNull; // Remember - No Compilation Error

  但是当你运行上面的代码片段的时候,你会在控制台上看到主线程抛出空指针异常。在使用HashMap和Integer键值的时候会发生很多这样的错误。当你运行下面代码的时候就会出现错误。

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&#39;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变量。


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn