Che cosa è null in Java?
Che cos'è null
?
null
è un'istanza di qualcosa?
A quale set appartiene null
?
Come viene rappresentato nella memoria?
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
ètrue
se il valore di RelationalExpression non ènull
e il riferimento può essere lanciato a ReferenceType senza generare unClassCastException
. 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 . Ilnull
il riferimento è l'unico valore possibile di un'espressione di tipo null. Il riferimentonull
può sempre essere lanciato su qualsiasi tipo di riferimento. In pratica, il programmatore può ignorare il tipo null e fingere chenull
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)
dovrebbereturn 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, onull
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 dinull
non indica necessariamente che la mappa non contiene alcuna mappatura per la chiave; è anche possibile che la mappa associ esplicitamente la chiave anull
. L'operazionecontainsKey
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, null
può 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 riferimentonull
, 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.
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.)
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.
No non è l'istanza di nulla, instanceof sarà sempre false.
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 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.
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);
null
è un valore speciale, non è istanza di nulla. Per ovvio motivo non può essere instanceof
nulla.
Rappresentazione bytecode
null
di Java ha il supporto JVM diretto: vengono utilizzate tre istruzioni per implementarlo:
-
aconst_null
: ad esempio per impostare una variabile sunull
come inObject o = null;
-
ifnull
eifnonnull
: ad esempio per confrontare un oggetto connull
come inif (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);
}
}
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.
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
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.
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.