Was ist null in Java?


252

Was ist null?

Ist nulleine Instanz von irgendetwas?

Zu welchem ​​Set nullgehört das?

Wie ist es in der Erinnerung dargestellt?


yegor256. Über null von JLS. "Das Null-Literal. Der Null-Typ hat einen Wert, die Null-Referenz, dargestellt durch das Null-Literal Null, das aus ASCII-Zeichen gebildet wird. Ein Null-Literal ist immer vom Null-Typ." Über Punkte im Artikel. 'Veränderbare und unvollständige Objekte' ist eine Funktion. 'Langsames Versagen' ist eine Fähigkeit von Natur aus. "Computer Thinking vs. Object Thinking" sind nur zwei Denkweisen. 'Ambiguous Semantic' ist zu subjektiv. "Ad-hoc-Fehlerbehandlung" ist eine andere Art der Arbeit mit Fehlern. Null ist ein Literal oder etwas anderes, das in JLS angegeben ist, im Gegensatz dazu, dass es nicht gut oder schlecht ist.
Oleksii Kyslytsyn

Antworten:


310

Ist null eine Instanz von irgendetwas?

Nein, es gibt keinen Typ, der ein nullist instanceof.

15.20.2 Typvergleichsoperator instanceof

RelationalExpression:
    RelationalExpression instanceof ReferenceType

Zur Laufzeit ist das Ergebnis des instanceofOperators, truewenn der Wert von RelationalExpression nicht lautet nullund die Referenz in den ReferenceType umgewandelt werden kann, ohne a auszulösen ClassCastException. Ansonsten ist das Ergebnis false.

Dies bedeutet, dass für jeden Typ Eund Rfür jeden E o, wo o == null, o instanceof Rimmer ist false.


Zu welcher Menge gehört 'null'?

JLS 4.1 Die Arten von Typen und Werten

Es gibt auch einen speziellen Nulltyp , den Typ des Ausdrucks null, der keinen Namen hat. Da der Nulltyp keinen Namen hat, ist es unmöglich , eine Variable des deklarieren null Typs oder Umwandlung in dem null - Typ. Die nullReferenz ist der einzig mögliche Wert eines Ausdrucks vom Typ Null . Die nullReferenz kann immer in einen beliebigen Referenztyp umgewandelt werden. In der Praxis kann der Programmierer den Nulltyp ignorieren und einfach so tun, nullals wäre dies nur ein spezielles Literal, das von einem beliebigen Referenztyp sein kann.


Was ist null?

Wie das obige JLS-Zitat sagt, können Sie in der Praxis einfach so tun, als wäre es "nur ein spezielles Literal, das von jedem Referenztyp sein kann".

In Java null == null(dies ist in anderen Sprachen nicht immer der Fall). Beachten Sie auch, dass es vertraglich auch diese besondere Eigenschaft (von java.lang.Object) hat:

public boolean equals(Object obj)

Für jeden Nicht - nullReferenzwert x, x.equals(null)sollte return false.

Dies ist auch der Standardwert (für Variablen mit diesen) für alle Referenztypen:

JLS 4.12.5 Anfangswerte von Variablen

  • Jede Klassenvariable, Instanzvariable oder Array-Komponente wird beim Erstellen mit einem Standardwert initialisiert :
    • Für alle Referenztypen ist der Standardwert null.

Wie dies verwendet wird, ist unterschiedlich. Sie können es verwenden, um die sogenannte verzögerte Initialisierung von Feldern zu aktivieren , bei der ein Feld seinen Anfangswert haben würde, nullbis es tatsächlich verwendet wird, wobei es durch den "echten" Wert ersetzt wird (dessen Berechnung teuer sein kann).

Es gibt auch andere Verwendungszwecke. Nehmen wir ein reales Beispiel aus java.lang.System:

public static Console console()

Rückgabe : Andernfalls die Systemkonsole, falls vorhanden null.

Dies ist ein sehr häufiges Verwendungsmuster: nullWird verwendet, um die Nichtexistenz eines Objekts anzuzeigen.

Hier ist ein weiteres Anwendungsbeispiel, diesmal von java.io.BufferedReader:

public String readLine() throws IOException

Rückgabe : A Stringenthält den Inhalt der Zeile, enthält keine Zeilenabschlusszeichen oder nullwenn das Ende des Streams erreicht wurde.

Also hier readLine()würde instanceof Stringfür jede Zeile zurückkehren, bis es schließlich ein zurückgibt null, um das Ende zu kennzeichnen. Auf diese Weise können Sie jede Zeile wie folgt verarbeiten:

String line;
while ((line = reader.readLine()) != null) {
   process(line);
}

Man kann die API so entwerfen, dass die Beendigungsbedingung nicht von der readLine()Rückgabe abhängt null, aber man kann sehen, dass dieses Design den Vorteil hat, die Dinge kurz zu machen. Beachten Sie, dass es kein Problem mit leeren Zeilen gibt, da es sich um eine leere Zeile handelt "" != null.

Nehmen wir ein weiteres Beispiel, diesmal von java.util.Map<K,V>:

V get(Object key)

Gibt den Wert zurück, dem der angegebene Schlüssel zugeordnet ist oder nullwenn diese Zuordnung keine Zuordnung für den Schlüssel enthält.

Wenn diese Zuordnung nullWerte zulässt , bedeutet ein Rückgabewert von nullnicht unbedingt, dass die Zuordnung keine Zuordnung für den Schlüssel enthält. Es ist auch möglich, dass die Karte den Schlüssel explizit zuordnet null. Die containsKeyOperation kann verwendet werden, um diese beiden Fälle zu unterscheiden.

Hier beginnen wir zu sehen, wie die Verwendung nulldie Dinge komplizieren kann. Die erste Anweisung besagt, dass, wenn der Schlüssel nicht zugeordnet nullist, zurückgegeben wird. Die zweite Anweisung besagt, dass der Schlüssel auch dann zurückgegeben werden nullkann , wenn er zugeordnet ist .

Im Gegensatz dazu wird java.util.Hashtabledie Sache einfacher, indem nullSchlüssel und Werte nicht zugelassen werden. sein V get(Object key), wenn zurückkehrt null, bedeutet eindeutig , dass der Schlüssel nicht abgebildet wird.

Sie können den Rest der APIs durchlesen und herausfinden, wo und wie sie nullverwendet werden. Denken Sie daran, dass dies nicht immer die Best-Practice- Beispiele sind.

Im Allgemeinen nullwerden sie als besonderer Wert verwendet, um Folgendes zu kennzeichnen:

  • Nicht initialisierter Zustand
  • Kündigungsbedingung
  • Nicht vorhandenes Objekt
  • Ein unbekannter Wert

Wie ist es in der Erinnerung dargestellt?

In Java? Geht dich nichts an. Und das ist am besten so.


Ist nulleine gute Sache?

Dies ist jetzt grenzwertig subjektiv. Einige Leute sagen, nulldass dies viele Programmiererfehler verursacht, die hätten vermieden werden können. Einige sagen, dass es in einer Sprache, die NullPointerExceptionwie Java funktioniert, gut ist, sie zu verwenden, da Sie bei Programmiererfehlern schnell ausfallen werden. Einige Leute vermeiden dies, nullindem sie Null-Objektmuster usw. verwenden.

Dies ist ein großes Thema für sich, daher wird es am besten als Antwort auf eine andere Frage diskutiert.

Ich werde dies mit einem Zitat des Erfinders von sich nullselbst, CAR Hoare (von schnellem Ruhm), beenden :

Ich nenne es meinen Milliardenfehler. Es war die Erfindung der nullReferenz im Jahr 1965. Zu dieser Zeit entwarf ich das erste umfassende Typensystem für Referenzen in einer objektorientierten Sprache (ALGOL W). Mein Ziel war es sicherzustellen, dass jede Verwendung von Referenzen absolut sicher ist, wobei die Überprüfung automatisch vom Compiler durchgeführt wird. Aber ich konnte der Versuchung nicht widerstehen, eine nullReferenz einzutragen, einfach weil es so einfach zu implementieren war. Dies hat zu unzähligen Fehlern, Schwachstellen und Systemabstürzen geführt, die in den letzten vierzig Jahren wahrscheinlich eine Milliarde Dollar an Schmerzen und Schäden verursacht haben.

Das Video dieser Präsentation geht tiefer; Es ist eine empfohlene Uhr.


4
In LISP (as NIL) gab es 1960 und wahrscheinlich früher keine Referenzen . Aber ich glaube nicht, dass Hoare wirklich versucht, die Erfindung von Nullreferenzen in diesem Zitat zu beanspruchen.
Stephen C

7
Hoare versucht nicht, die Erfindung von Nullreferenzen zu beanspruchen; er behauptet lediglich, er habe sie an einem besonders einflussreichen Ort zur Verfügung gestellt. Es gibt viele Sprachen, einschließlich Java, die eindeutig von Algol inspiriert wurden, und wenn ihre Verwendung von Nullreferenzen sogar teilweise von Algol inspiriert oder von Algol kopiert wurde, übernimmt Hoare zu Recht einen Teil der Schuld für die Kosten dieser. Ich habe jedoch das Gefühl, dass seine Schätzung eher niedrig ist. Eine Billion Dollar könnte näher an den tatsächlichen Kosten liegen.
cjs

32

Ist null eine Instanz von irgendetwas?

Deshalb null instanceof Xwird falsefür alle Klassen zurückkehren X. (Lassen Sie sich nicht von der Tatsache täuschen, dass Sie nulleiner Variablen zuweisen können, deren Typ ein Objekttyp ist. Genau genommen beinhaltet die Zuweisung eine implizite Typkonvertierung; siehe unten.)

Zu welcher Menge gehört 'null'?

Es ist das einzige Mitglied des Nulltyps, wobei der Nulltyp wie folgt definiert ist:

"Es gibt auch einen speziellen Null-Typ, den Typ des Ausdrucks null, der keinen Namen hat. Da der Null-Typ keinen Namen hat, ist es unmöglich, eine Variable vom Null-Typ zu deklarieren oder in den Null-Typ umzuwandeln. Die Null Referenz ist der einzig mögliche Wert eines Ausdrucks vom Typ Null. Die Nullreferenz kann immer in einen beliebigen Referenztyp umgewandelt werden. In der Praxis kann der Programmierer den Nulltyp ignorieren und einfach so tun, als wäre Null lediglich ein spezielles Literal, das von einem beliebigen Typ sein kann Referenztyp." JLS 4.1

Was ist null?

Siehe oben. In einigen Kontexten nullwird "kein Objekt" oder "unbekannt" oder "nicht verfügbar" bezeichnet, aber diese Bedeutungen sind anwendungsspezifisch.

Wie ist es in der Erinnerung dargestellt?

Das ist implementierungsspezifisch, und Sie können die Darstellung nullin einem reinen Java-Programm nicht sehen. ( nullWird jedoch in den meisten, wenn nicht allen Java-Implementierungen als Null-Maschinenadresse / -zeiger dargestellt.)


14

Was ist null?

Es ist nichts.

Ist null eine Instanz von irgendetwas?

Nein, da es nichts ist. Es kann keine Instanz von irgendetwas sein.

Zu welcher Menge gehört null?

Kein Satz

Wie ist es in der Erinnerung dargestellt?

Wenn einige Verweise darauf wie folgt lauten:

Object o=new Object();

Im Heapspeicher wird dem neu erstellten Objekt etwas Speicherplatz zugewiesen. Und o zeigt auf den zugewiesenen Speicherplatz.

Jetzt o=null;

Dies bedeutet, dass o jetzt nicht auf diesen Speicherbereich des Objekts zeigt.


1
"Jetzt o = null; Dies bedeutet, dass o jetzt nicht auf diesen Speicherbereich des Objekts zeigt." Ich denke, so funktioniert Garbage Collection in JAVA
Hardik Mishra

9

Nein, es ist nicht die Instanz von irgendetwas, die Instanz von wird immer falsch sein.


7

Das Schlüsselwort null ist ein Literal, das eine Nullreferenz darstellt , die auf kein Objekt verweist . null ist der Standardwert von Variablen vom Referenztyp.

Vielleicht auch mal reinschauen

null: Java-Glossar


2
Es ist kein Schlüsselwort, es ist ein Literal . Schlechte Qualität und nicht normatives Zitieren.
Marquis von Lorne

6

Null ist keine Instanz einer Klasse.

Sie können jedoch Variablen eines beliebigen (Objekt- oder Array-) Typs null zuweisen:

 // this is false   
 boolean nope = (null instanceof String);

 // but you can still use it as a String
 String x = null;
 "abc".startsWith(null);

6

Null in Java (tm)

In C und C ++ ist "NULL" eine in einer Header-Datei definierte Konstante mit einem Wert wie:

    0

oder:

    0L

oder:

    ((void*)0)

abhängig von den Optionen des Compilers und des Speichermodells. NULL ist streng genommen nicht Teil von C / C ++.

In Java (tm) ist "null" kein Schlüsselwort, sondern ein spezielles Literal vom Typ null. Es kann in einen beliebigen Referenztyp umgewandelt werden, jedoch nicht in einen primitiven Typ wie int oder boolean. Das Null-Literal muss nicht unbedingt den Wert Null haben. Und es ist unmöglich, in den Null-Typ umzuwandeln oder eine Variable dieses Typs zu deklarieren.


5

Bytecode-Darstellung

Java nullhat direkte JVM-Unterstützung: Drei Anweisungen werden verwendet, um es zu implementieren:

  • aconst_null: zB um eine Variable auf nullwie in zu setzenObject o = null;
  • ifnullund ifnonnull: zB um ein Objekt mit nullwie in zu vergleichenif (o == null)

In Kapitel 6 "Der Befehlssatz für Java Virtual Machine" werden dann die Auswirkungen nullauf andere Anweisungen erwähnt: NullPointerExceptionFür viele von ihnen wird ein a ausgelöst.

2.4. "Referenztypen und Werte" erwähnt auch nullallgemein:

Ein Referenzwert kann auch die spezielle Nullreferenz sein, eine Referenz auf kein Objekt, die hier mit Null bezeichnet wird. Die Nullreferenz hat anfangs keinen Laufzeittyp, kann jedoch in einen beliebigen Typ umgewandelt werden. Der Standardwert eines Referenztyps ist null.


4

nullist ein besonderer Wert, es ist keine Instanz von irgendetwas. Aus offensichtlichem Grund kann es instanceofnichts sein.


3

nullist ein spezieller Wert, der keine Instanz einer Klasse ist. Dies wird durch das folgende Programm veranschaulicht:

public class X {
   void f(Object o)
   { 
      System.out.println(o instanceof String);   // Output is "false"
   }
   public static void main(String[] args) {
      new X().f(null);
   }
}

6
Das einzige, was dieses Beispiel zeigt, ist, dass nulles sich nicht um eine Instanz von handelt String.
Sasha Chedygov

4
Wenn Sie die Signatur in ändern void f(String o), ist dies sinnvoller.
Thilo

2

null in Java ist wie / ähnlich wie nullptr in C ++.

Programm in C ++:

class Point
{
    private:
       int x;
       int y;
    public:
       Point(int ix, int iy)
       {
           x = ix;
           y = iy;
       }
       void print() { std::cout << '(' << x << ',' << y << ')'; }
};
int main()
{
    Point* p = new Point(3,5);
    if (p != nullptr)
    {
       p->print();
       p = nullptr;
    }
    else
    {
        std::cout << "p is null" << std::endl;
    }
    return 0;
}

Gleiches Programm in Java:

public class Point {
    private int x;
    private int y;
    public Point(int ix, int iy) {
        x = ix;
        y = iy;
    }
    public void print() { System.out.print("(" + x + "," + y + ")"); }
}
class Program
{
    public static void main(String[] args) {
        Point p = new Point(3,5);
        if (p != null)
        {
            p.print();
            p = null;
        }
        else
        {
            System.out.println("p is null");
        }
    }
}

Verstehen Sie nun anhand der obigen Codes, was in Java null ist? Wenn nein, dann empfehle ich Ihnen, Zeiger in C / C ++ zu lernen, und dann werden Sie verstehen.

Beachten Sie, dass in C im Gegensatz zu C ++ nullptr undefiniert ist, aber stattdessen NULL verwendet wird, was auch in C ++ verwendet werden kann. In C ++ ist nullptr jedoch vorzuziehen als nur NULL, da NULL in C immer mit Zeigern zusammenhängt und das ist In C ++ wurde das Suffix "ptr" an das Ende des Wortes angehängt, und auch alle Buchstaben sind jetzt in Kleinbuchstaben geschrieben, dies ist jedoch weniger wichtig.

In Java verweist jede Variable der nicht primitiven Typklasse immer auf ein Objekt dieses Typs oder wird geerbt, und null ist eine Objektreferenz der Nullklasse, jedoch kein Nullzeiger, da es in Java keinen solchen "Zeiger" gibt, sondern Verweise auf die Klasse Stattdessen werden Objekte verwendet, und null in Java bezieht sich auf Klassenobjektreferenzen. Sie können es also auch als "nullref" oder "nullrefobj" bezeichnen. Dies ist jedoch lang. Nennen Sie es einfach "null".

In C ++ können Sie Zeiger und den Wert nullptr für optionale Mitglieder / Variablen verwenden, dh Mitglied / Variable, die keinen Wert hat. Wenn sie keinen Wert hat, entspricht sie nullptr. So kann beispielsweise null in Java verwendet werden.


1

In Java gibt es zwei Hauptkategorien von Typen: Primitiv und Referenz . Variablen, die für Speicherwerte eines primitiven Typs deklariert wurden; Variablen, die von einem Referenztyp deklariert wurden, speichern Referenzen.

String x = null;

In diesem Fall deklariert die Initialisierungsanweisung eine Variable "x". "X" speichert die String-Referenz. Hier ist es null . Erstens ist null keine gültige Objektinstanz, daher ist ihr kein Speicher zugewiesen. Es ist einfach ein Wert, der angibt, dass sich die Objektreferenz derzeit nicht auf ein Objekt bezieht.


0

Eine interessante Möglichkeit, meiner Meinung nach null in Java zu sehen, besteht darin, es als etwas zu betrachten, das NICHT das Fehlen von Informationen bedeutet, sondern einfach als einen wörtlichen Wert, der einer Referenz eines beliebigen Typs zugewiesen werden kann. Wenn Sie darüber nachdenken, ob es sich um das Fehlen von Informationen handelt, ist es nicht sinnvoll, dass a1 == a2 wahr ist (falls beiden der Wert null zugewiesen wurde), da sie tatsächlich auf ein beliebiges Objekt verweisen könnten (wir einfach Ich weiß nicht, auf welche Objekte sie zeigen sollen.) ... Übrigens gibt null == null in Java true zurück. Wenn Java zB wie SQL: 1999 wäre, würde null == null unbekannt zurückgeben (ein boolescher Wert in SQL: 1999 kann drei Werte annehmen: wahr, falsch und unbekannt, aber in der Praxis wird unbekannt in realen Systemen als null implementiert) ... http://en.wikipedia.org/wiki/SQL


0

Kurze und präzise Antwort, die alle Ihre Fragen formell von JLS beantwortet:

3.10.7. Das Null-Literal

Der Nulltyp hat einen Wert, die Nullreferenz, dargestellt durch das Nullliteral Null, das aus ASCII-Zeichen gebildet wird.

Ein Null-Literal ist immer vom Null-Typ.

Es wird nur eine Referenz vom Typ zugewiesen, die null zugewiesen ist. Sie weisen der Referenz keinen Wert (Objekt) zu. Eine solche Zuordnung ist spezifisch für JVM, wie viel Referenz benötigt wird und in welchem ​​Speicherbereich sie zugewiesen wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.