Che cosa è null in Java?


Che cos'è null?

null è un'istanza di qualcosa?

A quale set appartiene null?

Come viene rappresentato nella memoria?

Author: Joachim Sauer, 2010-04-25

14 answers

Null è un'istanza di qualcosa?

No, non esiste un tipo che null sia un instanceof.

15.20.2 Tipo Operatore di confrontoinstanceof

RelationalExpression:
    RelationalExpression instanceof ReferenceType

In fase di esecuzione, il risultato dell'operatore instanceof è truese il valore di RelationalExpression non è nulle il riferimento può essere lanciato a ReferenceType senza generare un ClassCastException. Altrimenti il risultato è false.

Ciò significa che per qualsiasi digitare E e R, per qualsiasi E o, dove o == null, o instanceof R è sempre false.


A quale set appartiene 'null'?

JLS 4.1 I tipi di tipi e valori

Esiste anche un tipo speciale null, il tipo dell'espressione null, che non ha nome. Poiché il tipo null non ha nome, è impossibile dichiarare una variabile del tipo null o eseguire il cast sul tipo null . Il null il riferimento è l'unico valore possibile di un'espressione di tipo null. Il riferimento null può sempre essere lanciato su qualsiasi tipo di riferimento. In pratica, il programmatore può ignorare il tipo null e fingere che null sia semplicemente un letterale speciale che può essere di qualsiasi tipo di riferimento.


Che cos'è null?

Come dice la citazione JLS sopra, in pratica puoi semplicemente fingere che sia " semplicemente un letterale speciale che può essere di qualsiasi riferimento tipo".

In Java, null == null (questo non è sempre il caso in altre lingue). Si noti inoltre che per contratto, ha anche questa proprietà speciale (da java.lang.Object):

public boolean equals(Object obj)

Per qualsiasi valore di riferimento diverso da null x, x.equals(null) dovrebbe return false.

È anche il valore predefinito (per le variabili che li hanno) per tutti i tipi di riferimento:

JLS 4.12.5 Valori iniziali delle variabili

  • Ogni variabile di classe, variabile di istanza o componente array viene inizializzata con un valore predefinito quando viene creata:
    • Per tutti i tipi di riferimento, il valore predefinito è null.

Il modo in cui viene utilizzato varia. Puoi usarlo per abilitare quella che viene chiamata inizializzazione pigra dei campi, in cui un campo avrebbe il suo valore iniziale di null fino a quando non viene effettivamente utilizzato, dove viene sostituito dal valore " reale "(che può essere costoso da calcolare).

Ci sono anche altri usi. Prendiamo un esempio reale da java.lang.System:

public static Console console()

Restituisce: La console di sistema, se presente, altrimenti null.

Questo è un modello di uso molto comune: null è usato per indicare la non esistenza di un oggetto.

Ecco un altro esempio di utilizzo, questa volta da java.io.BufferedReader:

public String readLine() throws IOException

Restituisce: A String contenente il contenuto della riga, esclusi i caratteri di terminazione della riga, o null se è stata raggiunta la fine del flusso.

Quindi qui, readLine() restituirebbe instanceof String per ogni riga, fino a quando non restituisce finalmente un null per indicare la fine. Ciò consente di elaborare ogni riga come segue:

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

Si può progettare l'API in modo che la condizione di terminazione non dipenda da readLine() che restituisce null, ma si può vedere che questo progetto ha il vantaggio di fare cose concise. Si noti che non vi è alcun problema con le righe vuote, perché una riga vuota "" != null.

Prendiamo un altro esempio, questa volta da java.util.Map<K,V>:

V get(Object key)

Restituisce il valore a cui è mappata la chiave specificata o null se questa mappa non contiene alcuna mappatura per la chiave.

Se questa mappa consente valori null, un valore restituito di null non indica necessariamente che la mappa non contiene alcuna mappatura per la chiave; è anche possibile che la mappa associ esplicitamente la chiave a null. L'operazione containsKey può essere utilizzata per distinguere questi due casi.

Qui iniziamo a vedere come l'uso di null può complicare le cose. La prima istruzione dice che se la chiave non è mappata, viene restituito null. La seconda istruzione dice che anche se la chiave è mappata, nullpuò anche essere restituito.

Al contrario, java.util.Hashtable mantiene le cose più semplici non permettendo chiavi e valori null; il suo V get(Object key), se restituisce null, significa inequivocabilmente che la chiave non è mappata.

È possibile leggere il resto delle API e trovare dove e come viene utilizzato null. Tieni presente che non sono sempre gli esempi di best practice .

In generale, null sono usati come valore speciale per significare:

  • Stato non inizializzato
  • Condizione di terminazione
  • Oggetto non esistente
  • Un valore sconosciuto

Come è rappresentato nella memoria?

In Java? Non ti riguarda. Ed è meglio tenerlo così.


null è una buona cosa?

Questo è ora soggettivo borderline. Alcune persone dicono che null causa molti errori del programmatore che avrebbero potuto essere evitati. Alcuni dicono che in un linguaggio che cattura NullPointerException come Java, è bene usarlo perché fallirai-velocemente sugli errori del programmatore. Alcune persone evitano null usando Modello di oggetto nullo, ecc.

Questo è un argomento enorme da solo, quindi è meglio discusso come risposta a un'altra domanda.

Finirò con una citazione dall'inventore di null se stesso, C. A. R Hoare (di fama quicksort):

Lo chiamo il mio errore da un miliardo di dollari. Fu l'invenzione del riferimento null nel 1965. A quel tempo, stavo progettando il primo sistema di tipi completo per i riferimenti in un linguaggio orientato agli oggetti (ALGOL W). Il mio obiettivo era assicurarsi che tutto l'uso dei riferimenti sia assolutamente sicuro, con il controllo eseguito automaticamente dal compilatore. Ma non ho potuto resistere alla tentazione di inserire un riferimento null, semplicemente perché era così facile da implementare. Ciò ha portato a innumerevoli errori, vulnerabilità e crash di sistema, che hanno probabilmente causato un miliardo di dollari di dolore e danni negli ultimi quarant'anni.

Il video di questa presentazione va più in profondità; è un orologio consigliato.

 288
Author: polygenelubricants, 2015-08-25 13:23:01

Null è un'istanza di qualcosa?

N. Ecco perché null instanceof X restituirà false per tutte le classi X. (Non lasciarti ingannare dal fatto che puoi assegnare null a una variabile il cui tipo è un tipo di oggetto. A rigor di termini, l'assegnazione comporta una conversione di tipo implicita; vedi sotto.)

A quale set appartiene 'null'?

È l'unico membro del tipo null, dove il tipo null è definito come segue:

"Esiste anche un tipo null speciale, il tipo dell'espressione null, che non ha nome. Poiché il tipo null non ha nome, è impossibile dichiarare una variabile del tipo null o eseguire il cast sul tipo null. Il riferimento null è l'unico valore possibile di un'espressione di tipo null. Il riferimento null può sempre essere lanciato su qualsiasi tipo di riferimento. In pratica, il programmatore può ignorare il tipo null e fingere che null sia semplicemente un letterale speciale che può essere di qualsiasi tipo di riferimento." JLS 4.1

Che cos'è null?

Vedi sopra. In alcuni contesti, null è usato per indicare "nessun oggetto" o "sconosciuto" o "non disponibile", ma questi significati sono specifici dell'applicazione.

Come viene rappresentato nella memoria?

È specifico per l'implementazione e non sarà possibile vedere la rappresentazione di null in un programma Java puro. (Ma null è rappresentato come un indirizzo / puntatore macchina zero in la maggior parte se non tutte le implementazioni Java.)

 27
Author: Stephen C, 2012-10-24 01:32:40

Che cosa è null?

Non è nulla.

Null è un'istanza di qualcosa?

No come non è niente Non può essere istanza di nessuna cosa.

A quale set appartiene null?

Nessun set

Come è rappresentato nella memoria?

Se alcuni punti di riferimento ad esso come:

Object o=new Object();

Nella memoria heap un po ' di spazio assegnato al nuovo oggetto creato. E o punterà a quello spazio assegnato in memoria.

Ora o=null;

Questo significa che ora o non punterà a quello spazio di memoria dell'oggetto.

 13
Author: Sanjay Jain, 2011-08-31 14:31:01

No non è l'istanza di nulla, instanceof sarà sempre false.

 8
Author: Tom, 2010-04-25 06:00:24

La parola chiave null è un letterale che rappresenta un riferimento null, uno che non si riferisce ad alcun oggetto. null è il valore predefinito delle variabili di tipo di riferimento.

Forse anche dare un'occhiata a

Null: Glossario Java

 5
Author: Adriaan Stander, 2010-04-25 06:08:18

Null in Java (tm)

In C e C++, "NULL" è una costante definita in un file di intestazione, con un valore come:

    0

Oppure:

    0L

Oppure:

    ((void*)0)

A seconda delle opzioni del compilatore e del modello di memoria. NULL non è, in senso stretto, parte di C / C++ stesso.

In Java(tm), "null" non è una parola chiave, ma un letterale speciale del tipo null. Può essere lanciato su qualsiasi tipo di riferimento, ma non su qualsiasi tipo primitivo come int o booleano. Il letterale nullo non lo fa necessariamente avere valore zero. Ed è impossibile lanciare al tipo null o dichiarare una variabile di questo tipo.

 5
Author: p27, 2011-05-06 07:11:48

Null non è un'istanza di alcuna classe.

Tuttavia, è possibile assegnare null a variabili di qualsiasi tipo (oggetto o array):

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

 // but you can still use it as a String
 String x = null;
 "abc".startsWith(null);
 4
Author: Thilo, 2010-04-25 06:15:09

null è un valore speciale, non è istanza di nulla. Per ovvio motivo non può essere instanceof nulla.

 3
Author: fastcodejava, 2010-04-25 06:14:49

Rappresentazione bytecode

null di Java ha il supporto JVM diretto: vengono utilizzate tre istruzioni per implementarlo:

  • aconst_null: ad esempio per impostare una variabile su null come in Object o = null;
  • ifnull e ifnonnull: ad esempio per confrontare un oggetto con null come in if (o == null)

Il capitolo 6 "Il set di istruzioni della macchina virtuale Java" menziona quindi gli effetti di null su altre istruzioni: genera un NullPointerException per molte di esse.

2.4. "Tipi e valori di riferimento" menziona anche null in termini generici:

Un valore di riferimento può anche essere il riferimento null speciale, un riferimento a nessun oggetto, che sarà indicato qui da null. Il riferimento null inizialmente non ha alcun tipo di runtime, ma può essere lanciato su qualsiasi tipo. Il valore predefinito di un tipo di riferimento è null.

null è un valore speciale che non è un'istanza di alcuna classe. Questo è illustrato dal seguente programma:

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);
   }
}
 2
Author: Itay Maman, 2010-04-25 06:03:26

Null in Java è simile/simile a nullptr in C++.

Programma 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;
}

Stesso programma 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");
        }
    }
}

Ora capisci dai codici sopra cosa è null in Java? Se no, ti consiglio di imparare i puntatori in C/C++ e poi capirai.

Si noti che in C, a differenza di C++, nullptr non è definito, ma viene usato NULL, che può essere usato anche in C++, ma in C++ nullptr è più preferibile di un semplice NULL, perché il NULL in C è sempre relativo ai puntatori e basta, quindi in C++ il suffisso " ptr " è stato aggiunto alla fine della parola, e anche tutte le lettere sono ora minuscole, ma questo è meno importante.

In Java ogni variabile di tipo classe non primitiva è sempre riferimento a un oggetto di quel tipo o ereditato e null è riferimento a un oggetto di classe null, ma non a un puntatore null, perché in Java non esiste una cosa del genere "puntatore", ma i riferimenti agli oggetti di classe sono usati al posto, e null in Java è riferimenti, quindi puoi anche chiamarlo come "nullref" o "nullrefobj", ma questo è lungo, quindi chiamalo semplicemente "null".

In C++ puoi usare i puntatori e il valore nullptr per facoltativo membri/variabili, cioè membro/variabile che non ha valore e se non ha valore, allora è uguale a nullptr, quindi come null in Java può essere usato per esempio.

 1
Author: Farewell Stack Exchange, 2017-08-15 12:31:11

Un modo interessante per vedere null in java a mio parere è vederlo come qualcosa che NON denota un'assenza di informazioni ma semplicemente come un valore letterale che può essere assegnato a un riferimento di qualsiasi tipo. Se ci pensi se denotava assenza di informazioni, allora per a1==a2 essere vero non ha senso (nel caso in cui entrambi avessero assegnato un valore di null) in quanto potrebbero davvero puntare a QUALSIASI oggetto (semplicemente non sappiamo a quali oggetti dovrebbero puntare)... A proposito null = = null restituisce true in java. Se java ad esempio sarebbe come SQL: 1999, null = = null restituirebbe unknown (un valore booleano in SQL: 1999 può assumere tre valori: true, false e unknown ma in pratica unknown è implementato come null nei sistemi reali)... http://en.wikipedia.org/wiki/SQL

 0
Author: Bat0u89, 2013-11-28 19:55:57

Ci sono due categorie principali di tipi in Java: primitive ereference . Le variabili dichiarate di un tipo primitivo memorizzano i valori; le variabili dichiarate di un tipo di riferimento memorizzano i riferimenti.

String x = null;

In questo caso, l'istruzione di inizializzazione dichiara una variabile "x". "x" memorizza riferimento stringa. Qui è null. Prima di tutto, null non è un'istanza oggetto valida, quindi non c'è memoria allocata per esso. È semplicemente un valore che indica che l'oggetto riferimento non si riferisce attualmente a un oggetto.

 0
Author: Anand, 2017-01-29 19:33:50

Risposta breve e precisa che risponde formalmente a tutte le tue domande da JLS:

3.10.7. Il letterale Nullo

Il tipo null ha un valore, il riferimento null, rappresentato dal null letterale null, che è formato da caratteri ASCII.

Un letterale null è sempre del tipo null.

Viene assegnato solo un riferimento di tipo assegnato a null. Non si assegna alcun valore (oggetto) al riferimento. Quali l'allocazione è specifica per JVM quanto riferimento prenderà e in quale area di memoria verrà allocata.

 0
Author: Oleksii Kyslytsyn, 2017-07-13 10:03:45