Che cosa è null?
È nullun esempio di qualcosa?
A quale set nullappartiene?
Come viene rappresentato nella memoria?
Che cosa è null?
È nullun esempio di qualcosa?
A quale set nullappartiene?
Come viene rappresentato nella memoria?
Risposte:
Null è un'istanza di qualcosa?
No, non esiste un tipo che nullsia un instanceof.
instanceofRelationalExpression: RelationalExpression instanceof ReferenceTypeIn fase di esecuzione, il risultato
instanceofdell'operatore ètruese il valore di RelationalExpression non lo ènulle il riferimento potrebbe essere trasmesso a ReferenceType senza aumentare aClassCastException. Altrimenti il risultato èfalse.
Ciò significa che per qualsiasi tipo Ee R, per qualsiasi E o, dove o == null, o instanceof Rè sempre false.
A quale set appartiene 'null'?
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 . Ilnullriferimento è l'unico valore possibile di un'espressione di tipo null . Ilnullriferimento può sempre essere trasmesso a qualsiasi tipo di riferimento. In pratica, il programmatore può ignorare il tipo null e fingere semplicemente chenullsia semplicemente un letterale speciale che può essere di qualsiasi tipo di riferimento.
Cos'è null?
Come dice la citazione JLS sopra, in pratica puoi semplicemente fingere che sia "semplicemente un letterale speciale che può essere di qualsiasi tipo di riferimento".
In Java, null == null(questo non è sempre il caso in altre lingue). Nota anche che, per contratto, ha anche questa proprietà speciale (da java.lang.Object):
public boolean equals(Object obj)Per qualsiasi
nullvalore non di riferimentox,x.equals(null)dovrebbereturn false.
È anche il valore predefinito (per le variabili che li hanno) per tutti i tipi di riferimento:
- Ogni variabile di classe, variabile di istanza o componente dell'array viene inizializzata con un valore predefinito quando viene creata:
- Per tutti i tipi di riferimento, il valore predefinito è
null.
Come viene utilizzato varia. Puoi usarlo per abilitare quella che viene chiamata inizializzazione pigra dei campi, in cui un campo avrebbe il suo valore iniziale nullfino a quando non viene effettivamente utilizzato, dove viene sostituito dal valore "reale" (che può essere costoso da calcolare).
Ci sono anche altri usi. Facciamo un esempio reale da java.lang.System:
public static Console console()Restituisce : la console di sistema, se presente, altrimenti
null.
Questo è un modello di utilizzo molto comune: null viene utilizzato per indicare la non esistenza di un oggetto.
Ecco un altro esempio di utilizzo, questa volta da java.io.BufferedReader:
public String readLine() throws IOExceptionRestituisce : A
Stringcontenente il contenuto della riga, esclusi i caratteri di fine riga onullse è stata raggiunta la fine del flusso.
Quindi qui, readLine()tornerebbe instanceof Stringper ogni riga, fino a quando non restituisce infine a nullper indicare la fine. Ciò consente di elaborare ciascuna 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 dal readLine()ritorno null, ma si può vedere che questo disegno ha il vantaggio di rendere le cose concise. Si noti che non ci sono problemi con le righe vuote, perché una riga vuota "" != null.
Facciamo 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
nullse questa mappa non contiene alcuna mappatura per la chiave.Se questa mappa consente
nullvalori, un valore restituito dinullnon indica necessariamente che la mappa non contiene alcun mapping per la chiave; è anche possibile che la mappa associ esplicitamente la chiave anull. L'containsKeyoperazione può essere utilizzata per distinguere questi due casi.
Qui iniziamo a vedere come l'utilizzo nullpuò complicare le cose. La prima istruzione afferma che se la chiave non è mappata, nullviene restituita. La seconda affermazione afferma che anche se la chiave è mappata, nullpuò anche essere restituita.
Al contrario, java.util.Hashtablesemplifica le cose non consentendo nullchiavi e valori; è V get(Object key), se ritornanull , significa inequivocabilmente che la chiave non è mappata.
Puoi leggere il resto delle API e scoprire dove e come nullviene utilizzato. Tieni presente che non sono sempre le migliori pratiche esempi di .
In generale, nullvengono utilizzati come valore speciale per indicare:
Come viene rappresentato nella memoria?
In Java? Nessuna delle tue preoccupazioni. Ed è meglio conservarlo in questo modo.
nulluna buona cosa?Questo è ora soggettivo borderline. Alcune persone dicono che nullprovoca molti errori del programmatore che avrebbero potuto essere evitati. Alcuni dicono che in un linguaggio che cattura NullPointerExceptioncome Java, è bene usarlo perché fallirai velocemente sugli errori del programmatore. Alcune persone evitano nullusando il modello di oggetti Null , ecc.
Questo è un argomento enorme di per sé, quindi è meglio discuterne come risposta a un'altra domanda.
Concluderò con una citazione dell'inventore di nullse stesso, CAR Hoare (di fama quicksort):
Lo chiamo il mio errore da miliardi di dollari. Fu l'invenzione del
nullriferimento nel 1965. A quel tempo, stavo progettando il primo sistema di tipi completo per riferimenti in un linguaggio orientato agli oggetti (ALGOL W). Il mio obiettivo era quello di garantire che ogni uso dei riferimenti fosse assolutamente sicuro, con il controllo eseguito automaticamente dal compilatore. Ma non ho resistito alla tentazione di inserire unnullriferimento, semplicemente perché era così facile da implementare. Ciò ha portato a innumerevoli errori, vulnerabilità e arresti anomali del sistema, che probabilmente hanno causato un miliardo di dollari di dolore e danni negli ultimi quarant'anni.
Il video di questa presentazione va più in profondità; è un orologio raccomandato.
NIL) nel 1960 e probabilmente prima. Ma non credo che Hoare stia davvero cercando di rivendicare l'invenzione di riferimenti null in quella citazione.
Null è un'istanza di qualcosa?
No. Ecco perché null instanceof Xtornerà falseper tutte le classi X. (Non lasciarti ingannare dal fatto che puoi assegnare nulla 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'?
È il solo ed unico membro del tipo null, in cui 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 null il riferimento è l'unico valore possibile di un'espressione di tipo null. Il riferimento null può sempre essere castato su qualsiasi tipo di riferimento. In pratica, il programmatore può ignorare il tipo null e fingere semplicemente che null sia semplicemente un valore letterale speciale che può essere di qualsiasi tipo di riferimento ". JLS 4.1
Cos'è null?
Vedi sopra. In alcuni contesti, nullviene utilizzato per indicare "nessun oggetto" o "sconosciuto" o "non disponibile", ma questi significati sono specifici dell'applicazione.
Come viene rappresentato nella memoria?
Questo è specifico dell'implementazione e non sarai in grado di vedere la rappresentazione nullin un programma Java puro. (Ma nullè rappresentato come un indirizzo / puntatore macchina zero nella maggior parte se non in tutte le implementazioni Java.)
Cos'è null?
Non è niente.
Null è un'istanza di qualcosa?
No perché non è niente Non può essere un'istanza di nulla.
A quale set appartiene null?
Nessun set
Come viene rappresentato nella memoria?
Se alcuni riferimenti lo indicano come:
Object o=new Object();
Nella memoria heap dello spazio assegnato al nuovo oggetto creato. E o indicherà lo spazio assegnato in memoria.
Adesso o=null;
Ciò significa che ora o non punterà a quello spazio di memoria dell'oggetto.
La parola chiave null è un valore letterale che rappresenta un riferimento null, uno che non fa riferimento a nessun oggetto . null è il valore predefinito delle variabili del tipo di riferimento.
Forse anche dare un'occhiata
Null in Java (tm)
In C e C ++, "NULL" è una costante definita in un file di intestazione, con un valore come:
0
o:
0L
o:
((void*)0)
a seconda delle opzioni del compilatore e del modello di memoria. NULL non fa, in senso stretto, parte del C / C ++ stesso.
In Java (tm), "null" non è una parola chiave, ma un valore letterale speciale di tipo null. Può essere trasmesso a qualsiasi tipo di riferimento, ma non a qualsiasi tipo primitivo come int o booleano. Il valore letterale null non ha necessariamente valore zero. Ed è impossibile eseguire il cast sul tipo null o dichiarare una variabile di questo tipo.
Rappresentazione bytecode
Java nullha il supporto JVM diretto: per implementarlo vengono utilizzate tre istruzioni:
aconst_null: ad es. per impostare una variabile nullcome inObject o = null;ifnulle ifnonnull: ad esempio per confrontare un oggetto con nullcome inif (o == null)Il capitolo 6 "Il set di istruzioni della macchina virtuale Java" menziona quindi gli effetti di nullaltre istruzioni: ne lancia una NullPointerExceptionper molti.
2.4. "Tipi e valori di riferimento" menziona anche nullin termini generici:
Un valore di riferimento può anche essere lo speciale riferimento null, un riferimento a nessun oggetto, che qui verrà indicato da null. Il riferimento null inizialmente non ha un tipo di runtime, ma può essere trasmesso a qualsiasi tipo. Il valore predefinito di un tipo di riferimento è null.
nullè un valore speciale, non è un'istanza di nulla. Per ovvio motivo non può essere instanceofnulla.
nullè un valore speciale che non è un'istanza di nessuna 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);
}
}
nullnon è un'istanza di String.
void f(String o), avrebbe più senso.
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 che cosa è null in Java? In caso contrario, ti consiglio di imparare i puntatori in C / C ++ e quindi capirai.
Si noti che in C, a differenza di C ++, nullptr non è definito, ma viene utilizzato NULL, che può essere utilizzato anche in C ++, ma in C ++ nullptr è più preferibile rispetto a solo NULL, poiché NULL in C è sempre correlato ai puntatori e questo è quindi, in C ++ il suffisso "ptr" è stato aggiunto alla fine della parola, e anche tutte le lettere sono ora in minuscolo, ma questo è meno importante.
In Java ogni variabile di tipo di classe non primitiva fa sempre riferimento a oggetto di quel tipo o ereditato e null è riferimento a oggetto di classe null, ma non puntatore null, perché in Java non esiste un "puntatore", ma riferimenti alla classe vengono invece utilizzati oggetti e null in Java è correlato ai riferimenti agli oggetti di classe, quindi puoi anche chiamarlo "nullref" o "nullrefobj", ma questo è lungo, quindi chiamalo semplicemente "null".
In C ++ è possibile utilizzare i puntatori e il valore nullptr per membri / variabili opzionali , ovvero membro / variabile che non ha valore e se non ha alcun valore, allora è uguale a nullptr, quindi come può essere utilizzato null in Java.
Esistono due principali categorie di tipi in Java: primitiva e riferimento . Variabili dichiarate di valori di archivio di tipo primitivo; 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 il riferimento di stringa. È nullo qui. Prima di tutto, null non è un'istanza di oggetto valida, quindi non è stata allocata memoria per essa. È semplicemente un valore che indica che il riferimento all'oggetto non si riferisce attualmente a un oggetto.
Un modo interessante di vedere null in Java secondo me è 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 pensate se denotasse l'assenza di informazioni, allora che a1 == a2 fosse vero non ha senso (nel caso in cui a entrambi fosse assegnato un valore nullo) in quanto potrebbero davvero puntare a QUALSIASI oggetto (semplicemente non so a quali oggetti dovrebbero puntare) ... A proposito null == null restituisce true in java. Se java, ad esempio, fosse come SQL: 1999, allora null == null restituirebbe sconosciuto (un valore booleano in SQL: 1999 può assumere tre valori: vero, falso e sconosciuto, ma in pratica sconosciuto è implementato come nullo nei sistemi reali) ... http://en.wikipedia.org/wiki/SQL
Risposta breve e precisa che risponde formalmente a tutte le tue domande da JLS:
3.10.7. The Null Literal
Il tipo null ha un valore, il riferimento null, rappresentato dal null letterale null, che è formato da caratteri ASCII.
Un valore letterale null è sempre del tipo null.
Viene allocato solo un riferimento di tipo assegnato a null. Non si assegna alcun valore (oggetto) al riferimento. Tale allocazione è specifica per JVM di quanto riferimento prenderà e in quale area di memoria verrà allocata.