Null è un oggetto?


119

È null un Objectin Java?


41
No, non lo è, e per coloro che si chiedono perché una domanda del genere, ci sono linguaggi in cui null è davvero un oggetto come un qualsiasi, ad esempio Ruby.
JRL

7
In Scala, che è molto meticoloso sui tipi, c'è un tipo Null(un tratto , in realtà) che ha una singola istanza null.
Carl Smotricz

1
@JRL: Solo per curiosità, mi chiedo come questo influenzi il funzionamento di JRuby ... (non ho abbastanza familiarità con quel livello di implementazione per saperlo con certezza.)
Benjamin Oakes

Per aggiungere al commento di @ JRL - l'equivalente approssimativo di Ruby nullè nil, che è un'istanza di NilClass
Eliot Sykes,

O javascript, in cui null instanceof Objectè falso ma typeof(null)restituisce 'object'. È un oggetto in quel caso? Chissà.
Don Hatch

Risposte:


166

Se null fosse un oggetto, supporterebbe i metodi java.lang.Objectcome equals(). Tuttavia, questo non è il caso: qualsiasi invocazione di metodo su un valore null risulta in un file NullPointerException.

E questo è ciò che la specifica del linguaggio Java ha da dire su questo argomento:

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 di tipo null o eseguire il cast al tipo null. Il riferimento null è l'unico valore possibile di un'espressione di tipo null. È sempre possibile eseguire il cast del riferimento null a qualsiasi tipo di riferimento. In pratica, il programmatore può ignorare il tipo null e semplicemente fingere che null sia semplicemente un letterale speciale che può essere di qualsiasi tipo di riferimento.

Penso che questo possa essere ridotto a "null is special".


1
Quindi un oggetto in Java è un oggetto solo se è uguale o sottoclassi java.lang.Object. Praticamente - sì. Non è possibile creare una classe che non sia una sottoclasse di java.lang.Object, ma non ci ho mai pensato da un punto di vista più filosofico
Andreas Dolk

Curiosamente, tra tutte le cose, il documento API perNullPointerException fa menzione di un » nulloggetto«… :) Ma poi, andava bene anche parlare di »puntatori nulli«…
Lumi

Hai detto: "Il riferimento null può sempre essere convertito in qualsiasi tipo di riferimento". Quindi, possiamo restituire null (typecasted-se consentito) in un metodo con un tipo di riferimento (restituzione) oggetto?
Srichakradhar

1
@Srichakradhar: sì, possiamo! Che puoi scoprire più facilmente provandolo in codice che chiedendo qui.
Michael Borgwardt

1
"Il riferimento null è l'unico valore possibile di un'espressione di tipo null". È ora di leggere il documento delle Specifiche. :)
sofs1

32

Secondo le specifiche Java , nullè un tipo che può essere assegnato a una variabile oggetto (come valore come indicato nel commento). Tuttavia, non è possibile istanziare o creare variabili di questo tipo, è necessario utilizzare il valore letterale nullfornito dal compilatore.


8
null è un tipo e un valore.
Joachim Sauer

5
Il nullnome è una "istanza" del nulltipo, a quanto pare.
Strager

nullnon è una variabile, è un letterale: JLS, 3.10.7. The Null Literal
Gerold Broser

Re " nullè un tipo che può essere assegnato ": 1) null(nel codice) è il letterale nullo , non il tipo nullo 2) I tipi non possono essere assegnati alle variabili in Java in generale, vedere JLS 4.1: " Ci sono [... ] due tipi di valori di dati che possono essere memorizzati nelle variabili [...]: valori primitivi (§4.2) e valori di riferimento (§4.3). " È il riferimento nullo che può essere assegnato tramite il valore nullletterale. ... continua ...
Gerold Broser

3) oggetto in " variabile oggetto ", rispetto alla variabile di classe, solitamente non fa riferimento al tipo ma alla durata. Quando si fa riferimento al tipo, di solito viene chiamato variabile di un tipo di riferimento o, in breve, variabile di riferimento (tipo). Sono a conoscenza di 4 tipi nell'API Java che espongono variabili di istanza / oggetto (potrebbero essercene di più): array con le suelength e sottoclassi di java.awt.geom.Point2D.
Gerold Broser



12

Null è la mancanza di un oggetto.


Ma il tipo null è assegnabile a ogni tipo di riferimento.
Tom Hawtin - tackline

Non esiste un "tipo null"; null è un valore specifico di espressioni non primitive (cioè riferimenti; non esiste nemmeno un "tipo di riferimento" in Java, per quanto ne so).
Tommy McGuire

3
Tommy: JLS 4.1: "C'è anche uno speciale tipo null, il tipo dell'espressione null, che non ha nome."
Ken il


12

JRL ha scritto:

No non lo è, ...

Come spesso, dipende da dove lo guardi, a chi credi di più.

Secondo il JLS, sì, lo è . Soprattutto se riformuli la domanda in: "Il testo è nullletterale Object?". Oltre a JLS 4.1 citato da Michael Borgwardt sopra:

Vedere JLS 3.10.7 :

Un valore letterale null è sempre di tipo null.

e JLS 4.10 :

I sottotipi di un tipo T sono tutti i tipi U tali che T è un supertipo di U e il tipo null.

o JLS 4.10.2 :

I supertipi diretti del tipo null sono tutti tipi di riferimento diversi dal tipo null stesso.

[Sottolinea da me.]

Secondo il compilatore di Eclipse 2019-09 non è :

true.toString();  // Cannot invoke toString() on the primitive type boolean
null.toString();  // Cannot invoke toString() on the primitive type null

Secondo OpenJDKs 12.0.1 javac è :

true.toString();  // error: boolean cannot be dereferenced
null.toString();  // error: <null> cannot be dereferenced

Dove le parentesi angolari implicano che nullè di tipo diverso da quello primitivo. E secondo JLS 4.1 :

Esistono due tipi di tipi nel linguaggio di programmazione Java: tipi primitivi (...) e tipi di riferimento (...).

se non è l'uno è l'altro.


Claudiu ha scritto:

null è un po 'brutto.

Au contraire, nullè bellissimo. Cosa suggeriresti invece come valore predefinito per una variabile del tipo di riferimento? Una combinazione di bit arbitraria? Benvenuto alla violazione di accesso o, peggio ancora, all'inferno del puntatore!


Joachim Sauer ha scritto:

null è un tipo e un valore.

In realtà ci sono tre elementi in combinazione con null (vedere anche JLS 3.10.7 ):

  1. Il tipo null (altrimenti senza nome) .
  2. Il null letterale .
  3. Il valore di riferimento nullo . (Comunemente abbreviato come valore nullo o semplicemente nullo .)

(1) Si noti che, secondo JLS 4.10.2 sopra citato, il tipo null utilizza l'ereditarietà multipla non solo per le interfacce ma anche per le classi. Ciò che tutti sappiamo non è possibile per noi programmatori di applicazioni.

(2) Il letterale nullo potrebbe essere immaginato come una variabile definita come:

JVM_global final null_type null = new null_type();

Nota anche JLS 3.9 :

A volte si presume, erroneamente, che una varietà di sequenze di caratteri siano parole chiave:

  • nullnon è una parola chiave, ma piuttosto il letterale nullo ( §3.10.7 ).

circa null instanceof <any type>

Con JLS 4.10.2 in mente ("il tipo nullo è un sottotipo di ogni tipo") null instanceof <any type>dovrebbe essere valutato true, no? A prima vista, sì, ma JLS 15.20.2 dà la risposta insight:

[...] il risultato del instanceofgestore è truese il valore del RelationalExpression non ènull [...]. Altrimenti il ​​risultato èfalse .

[Sottolinea da me.]

Chiediti cosa ha più senso (dal punto di vista di un programmatore di applicazioni):

  • Dare falsee quindi indicare che un'espressione di riferimento non è di un tipo a noi esposto, ovvero indicare che non fa riferimento a nulla di utile per noi

  • o dando true, informandoci così che l'espressione valuta un riferimento speciale, il riferimento nullo , che fa riferimento a un "oggetto" di cui non sappiamo nemmeno se esiste e che è del tipo speciale nullo che non ha nome, non è esposto a us ma tramite il letterale null , è un sottotipo di qualsiasi tipo inclusa l'ereditarietà multipla e deve essere ignorato comunque? Considera anche l'esempio più pratico:

     class Car implements Vehicle {  
     ...
     Vehicle car = null;
     ...
     boolean b = car instanceof Car;  // True? There's not even an instance
     ...                              // which could be of type Car.

Il che porta anche a:

Perché instanceofnon è un modo corretto per dire qualcosa in meritonull sull'Oggetto di?

Si chiama instanceofno sameorsubtypeof. Ciò significa che stiamo confrontando il tipo di un'istanza con un tipo, non due tipi. Ora nullsignifica: "Non c'è nessuna istanza" e se non c'è nessuna istanza non c'è il tipo di istanza. È ovvio che il confronto tra nulla e qualcosa dovrebbe portare a false.

O in un esempio "più" del mondo reale:

  • Ho tra le mani un'immagine a grandezza naturale di una mela ( = tipo di riferimento ) con scritto »Big Apple« ( = nome del tipo di riferimento ).
  • C'è un tavolo ( = mucchio ) davanti a me.
  • Se c'è una mela ( = istanza ) sul tavolo c'è una corda ( = riferimento ) collegata ad essa.
  • Tengo l'altra estremità di questo cavo in mano ( = variabile di riferimento ).
  • Traccio la mela lungo il cordone e la confronto con la mia immagine ( = istanza di ).
  • Se la mela è della stessa dimensione o più grande dell'immagine, si applica la scritta "Big Apple" ( = vero ).
  • Se è più piccolo, allora no ( = false ).
  • Se non c'è una mela sul tavolo (= nessuna istanza ) e, quindi, non esiste alcun cavo ( = null ) la scrittura non si applica neanche ( = falso ). Perché: nessuna mela è una grande mela? No non lo è.


Come Michael riassume: "null è speciale" davvero.


2
Apple e null? Non hai paura di una causa legale? :)
Gábor Lipták

9

No, non è un'istanza di una classe né di una classe. Non è un riferimento a niente.

Modifica : non ho letto le specifiche, quindi quanto sopra potrebbe non essere accurato al 100%.


5

Come spiegato nel capitolo 4.1 I tipi di tipi e valori della specifica del linguaggio Java, null è un tipo che ha un valore, il riferimento null (ed è rappresentato dal letterale null):

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

Tuttavia, potresti voler leggere del motivo a oggetti nulli (che non consiglio). Vedi il C2 Wiki o Wikipedia per ulteriori informazioni su questo modello.



4

No, non è un oggetto in quanto l'istanza nulla di Object restituirà sempre false, inoltre c'è solo un null, non uno per ogni classe.


3
In effetti, null instanceof <anytype>tornerà falseanche.
Bombe

4

Secondo le specifiche Java ,

C'è anche uno speciale valore letterale null che può essere usato come valore per qualsiasi tipo di riferimento. null può essere assegnato a qualsiasi variabile, ad eccezione delle variabili di tipo primitivo. C'è poco che puoi fare con un valore nullo oltre a testare la sua presenza. Pertanto, null viene spesso utilizzato nei programmi come indicatore per indicare che alcuni oggetti non sono disponibili.


4

Java gestisce gli oggetti tramite riferimenti. Null è una ripartizione della OO-ness di Java, poiché ti fa scendere al di sotto del livello OO. No non è un oggetto è un VALORE di un riferimento. E non ha nulla a che fare con i paradigmi degli oggetti, ma si riferisce all'impianto idraulico di Java, che abilita gli oggetti.


3

Null è un'istanza di java.lang.Object? No.

Null è un oggetto ? dipende dalla definizione di " è ".


2
Object foo = null;
System.out.println(foo.toString()); 

La prima riga mostra nullpuò essere assegnata al tipo Object, ma la seconda riga dimostrerà che non è certamente un Objecte alla fine si traduce in ajava.lang.NullPointerException


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.