Nie, nie jest, a dla tych, którzy zastanawiają się, dlaczego takie pytanie, są języki, w których null jest rzeczywiście przedmiotem jak każdy, na przykład Ruby.
JRL
7
W Scali, która jest bardzo drobiazgowa co do typów, istnieje typ Null( właściwie cecha ) mający tylko jedną instancję null.
Carl Smotricz
1
@JRL: Tak z ciekawości, zastanawiam się, jak to wpływa na działanie JRuby ... (nie jestem wystarczająco zaznajomiony z tym poziomem implementacji, aby być pewnym).
Benjamin Oakes
Aby dodać do komentarza @ JRL - szorstki odpowiednik nullto Ruby nil, który jest instancją NilClass
Eliot Sykes
Lub javascript, w którym null instanceof Objectjest fałsz, ale typeof(null)zwraca 'object'. Czy w takim razie jest to przedmiot? Kto wie.
Don Hatch
Odpowiedzi:
166
Gdyby null był obiektem, obsługiwałoby metody java.lang.Objecttakie jak equals(). Jednak tak nie jest - każde wywołanie metody dla wartości null powoduje utworzenie pliku NullPointerException.
Istnieje również specjalny typ null, typ wyrażenia null, który nie ma nazwy. Ponieważ typ null nie ma nazwy, nie można zadeklarować zmiennej typu null ani rzutować na typ null. Odwołanie o wartości null jest jedyną możliwą wartością wyrażenia typu null. Odwołanie o wartości null można zawsze rzutować na dowolny typ odwołania. W praktyce programista może zignorować typ null
i po prostu udawać, że null jest tylko specjalnym literałem, który może być dowolnego typu referencyjnego.
Myślę, że można to sprowadzić do stwierdzenia, że „zero jest wyjątkowe”.
Zatem obiekt w Javie jest obiektem tylko wtedy, gdy jest równy lub podklasy java.lang.Object. Praktycznie - tak. Nie możesz stworzyć klasy, która nie jest podklasą java.lang.Object, ale nigdy nie myślałem o tym z bardziej filozoficznego punktu widzenia
Powiedziałeś: „Odniesienie zerowe może być zawsze rzutowane na dowolny typ odniesienia”. Czy możemy więc zwrócić wartość null (typecasted-if allowed) w metodzie z typem odwołania do obiektu (zwracanego)?
Srichakradhar
1
@Srichakradhar: tak, możemy! Które możesz dowiedzieć się łatwiej, wypróbowując to w kodzie, niż pytając tutaj.
Michael Borgwardt,
1
„Odniesienie zerowe jest jedyną możliwą wartością wyrażenia typu null”. Czas przeczytać dokument Specyfikacje. :)
sofs1
32
Według Java specyfikacji , nullto typ, który może być przypisany do zmiennej obiektowej (jako wartość jak zauważono w komentarzu). Nie możesz jednak tworzyć instancji ani tworzyć zmiennych tego typu, musisz użyć literału nulldostarczonego przez kompilator.
3) obiekt w „ zmiennej obiektowej ”, w porównaniu do zmiennej klasy, zwykle nie odnosi się do typu, ale do czasu życia. W odniesieniu do typu jest zwykle nazywana zmienną typu referencyjnego lub, w skrócie, zmienną referencyjną (typ). Zdaję sobie sprawę z 4 typów w Java API, które ujawniają zmienne instancji / obiektu (może być ich więcej): tablice z jegolength i podklasy java.awt.geom.Point2D.
Ale typ zerowy można przypisać do każdego typu referencyjnego.
Tom Hawtin - tackline
Nie ma „typu zerowego”; null jest określoną wartością nieprymitywnych wyrażeń (tj. odwołań; w moim rozumieniu również w Javie nie ma „typu referencyjnego”).
Tommy McGuire
3
Tommy: JLS 4.1: "Istnieje również specjalny typ null, typ wyrażenia null, który nie ma nazwy."
Jak często, zależy to od tego, skąd na to patrzysz, w kogo bardziej wierzysz.
Według JLS tak, jest . Zwłaszcza jeśli przeformułujesz pytanie na: „Czy nulltyp jest dosłowny Object?”. Oprócz JLS 4.1 cytowanego powyżej przez Michaela Borgwardta:
Bezpośrednie typy nadrzędne typu null są wszystkimi typami odwołań innymi niż sam typ null.
[Podkreśla przeze mnie.]
Według kompilatora Eclipse 2019-09 to nie jest :
true.toString();// Cannot invoke toString() on the primitive type booleannull.toString();// Cannot invoke toString() on the primitive type null
Według OpenJDKs 12.0.1 javacjest to :
true.toString();// error: boolean cannot be dereferencednull.toString();// error: <null> cannot be dereferenced
Gdzie nawiasy ostre sugerują, że nulljest to inny typ niż pierwotny. I zgodnie z JLS 4.1 :
W języku programowania Java istnieją dwa rodzaje typów: typy pierwotne (...) i typy referencyjne (...).
jeśli to nie to, to jest drugie.
Claudiu napisał:
null jest trochę brzydkie.
Au contraire, nulljest piękna. Co zamiast tego sugerowałbyś jako wartość domyślną dla zmiennej typu referencyjnego? Dowolna kombinacja bitów? Witamy w naruszeniu dostępu lub, co gorsza, w piekle wskaźnikowym!
Joachim Sauer napisał:
null to typ i wartość.
W rzeczywistości istnieją trzy elementy w połączeniu z wartością null (patrz także JLS 3.10.7 ):
Typ zerowy (inaczej nienazwany) .
nullDosłowny .
Wartość odniesienia zerowa . (Zwykle w skrócie jako wartość null lub po prostu null .)
(1) Należy zauważyć, że zgodnie z cytowanym powyżej JLS 4.10.2 typ zerowy wykorzystuje wielokrotne dziedziczenie nie tylko dla interfejsów, ale także dla klas. Co wszyscy wiemy, nie jest możliwe dla nas, programistów aplikacji.
(2) Pusty literał można sobie wyobrazić jako zmienną zdefiniowaną jako:
JVM_global final null_type null = new null_type();
Czasami błędnie zakłada się, że za słowa kluczowe są różne sekwencje znaków:
nullnie jest słowem kluczowym, ale raczej literałem zerowym ( §3.10.7 ).
O null instanceof <any type>
Mając na uwadze JLS 4.10.2 („ typ null jest podtypem każdego typu”) null instanceof <any type>powinno się oceniać true, prawda? Na pierwszy rzut oka tak, ale JLS 15.20.2 daje wgląd w odpowiedź:
[...] wynikiem tego instanceofoperatora jest true, jeśli wartość w RelationalExpression nie jestnull [...]. W przeciwnym razie wynik jestfalse .
[Podkreśla przeze mnie.]
Zadaj sobie pytanie, co ma większy sens (z punktu widzenia programisty aplikacji):
Podanie falsei tym samym wskazanie, że wyrażenie referencyjne nie jest typem dla nas ujawnionym, tj. Wskazanie, że nie odwołuje się do niczego użytecznego dla nas
lub podając true, w ten sposób informując nas, że wyrażenie zwraca się do specjalnego odniesienia, odniesienia zerowego , odnoszącego się do "obiektu", nie wiemy, czy on w ogóle istnieje i który jest specjalnego typu null, który nie ma nazwy, nie jest wystawiony my, ale czy poprzez literał null podtyp jest dowolnego typu, w tym dziedziczenie wielokrotne i czy i tak ma być ignorowany? Rozważ także bardziej praktyczny przykład:
classCarimplementsVehicle{...Vehicle car =null;...boolean b = car instanceofCar;// True? There's not even an instance...// which could be of type Car.
Co również prowadzi do:
Dlaczego instanceofnie można powiedzieć czegoś o nullprzedmiotowości we właściwy sposób ?
Nazywa się instanceofnie sameorsubtypeof. Oznacza to, że porównujemy typ instancji z typem, a nie dwoma typami. Teraz nulloznacza: „Nie ma instancji”, a jeśli nie ma instancji, nie ma typu instancji. To oczywiste, że porównywanie niczego z czymś ma prowadzić false.
Lub w „bardziej” realnym przykładzie:
W dłoniach mam zdjęcie jabłka ( = typ referencyjny ) z napisem »Big Apple« ( = nazwa typu odniesienia ).
Przede mną jest stół ( = stos ).
Jeśli na stole znajduje się jabłko ( = instancja ), jest do niego podłączony przewód ( = odniesienie ).
Trzymam w dłoni drugi koniec tego sznurka ( = zmienna referencyjna ).
Rysuję jabłko wzdłuż sznurka i porównuję je z moim zdjęciem ( = instanceof ).
Jeśli jabłko jest tej samej wielkości lub większe niż obrazek, stosuje się do niego napis »Wielkie Jabłko« ( = prawda ).
Jeśli jest mniejszy, to nie ( = fałsz ).
Jeśli na stole nie ma jabłka (= brak instancji ), a zatem nie ma sznurka ( = null ), zapis również nie ma zastosowania ( = fałsz ). Ponieważ: Czy żadne jabłko nie jest dużym jabłkiem? Nie, nie jest.
Jak podsumowuje Michael: „null jest naprawdę wyjątkowe”.
Jak wyjaśniono w rozdziale 4.1 Rodzaje typów i wartości specyfikacji języka Java, null to typ, który ma jedną wartość, odwołanie zerowe (i jest reprezentowane przez literał null):
Istnieje również specjalny typ null , typ wyrażenia null, który nie ma nazwy. Ponieważ typ null nie ma nazwy, nie można zadeklarować zmiennej typu null ani rzutować na typ null. Odwołanie o wartości null jest jedyną możliwą wartością wyrażenia typu null. Odwołanie o wartości null można zawsze rzutować na dowolny typ odwołania. W praktyce programista może zignorować typ zerowy i po prostu udawać, że nulljest to tylko specjalny literał, który może być dowolnego typu referencyjnego.
Możesz jednak przeczytać o wzorcu obiektu zerowego (którego nie polecam). Zobacz C2 Wiki lub Wikipedia, aby uzyskać więcej informacji na temat tego wzorca.
Istnieje również specjalny literał o wartości null, którego można użyć jako wartości dla dowolnego typu odwołania. null można przypisać do dowolnej zmiennej, z wyjątkiem zmiennych typu pierwotnego. Niewiele można zrobić z wartością zerową poza testowaniem jej obecności. Dlatego wartość null jest często używana w programach jako znacznik wskazujący, że jakiś obiekt jest niedostępny.
Java obsługuje obiekty za pośrednictwem odwołań. Null to podział OO-ności Javy, ponieważ spada poniżej poziomu OO. Nie, to nie jest przedmiot, to WARTOŚĆ odniesienia. I nie ma to nic wspólnego z paradygmatami obiektów, ale odnosi się do hydrauliki Javy, która umożliwia tworzenie obiektów.
Pierwsza linia pokazuje nullmoże być przypisana do typu Object, ale druga linia zademonstruje, że z pewnością nie jest Objecti ostatecznie daje w wynikujava.lang.NullPointerException
Null
( właściwie cecha ) mający tylko jedną instancjęnull
.null
to Rubynil
, który jest instancją NilClassnull instanceof Object
jest fałsz, aletypeof(null)
zwraca'object'
. Czy w takim razie jest to przedmiot? Kto wie.Odpowiedzi:
Gdyby null był obiektem, obsługiwałoby metody
java.lang.Object
takie jakequals()
. Jednak tak nie jest - każde wywołanie metody dla wartości null powoduje utworzenie plikuNullPointerException
.Oto, co na ten temat ma do powiedzenia specyfikacja języka Java :
Myślę, że można to sprowadzić do stwierdzenia, że „zero jest wyjątkowe”.
źródło
java.lang.Object
. Praktycznie - tak. Nie możesz stworzyć klasy, która nie jest podklasą java.lang.Object, ale nigdy nie myślałem o tym z bardziej filozoficznego punktu widzeniaNullPointerException
wspomina o »null
obiekcie«… :) Ale z drugiej strony można było również mówić o »zerowych wskaźnikach«…Według Java specyfikacji ,
null
to typ, który może być przypisany do zmiennej obiektowej (jako wartość jak zauważono w komentarzu). Nie możesz jednak tworzyć instancji ani tworzyć zmiennych tego typu, musisz użyć literałunull
dostarczonego przez kompilator.źródło
null
Nazwa to „przypadek” wnull
rodzaju, widocznie.null
nie jest zmienną, jest literałem: JLS, 3.10.7. The Null Literalnull
to typ, który można przypisać ": 1)null
(w kodzie) to literał zerowy , a nie typ pusty 2) Typów nie można przypisać do zmiennych w języku Java w ogólności, patrz JLS 4.1: " Istnieją [... ] dwa rodzaje wartości danych, które mogą być przechowywane w zmiennych [...]: wartości pierwotne (§4.2) i wartości odniesienia (§4.3). " Jest to odwołanie zerowe, które można przypisać za pomocąnull
literału. ... cd ...length
i podklasyjava.awt.geom.Point2D
.Absolutnie nie:
null instanceof Object
zwraca fałsz.źródło
Nie, to nie jest przedmiot.
źródło
Brak jest brakiem obiektu.
źródło
JRL napisał:
Jak często, zależy to od tego, skąd na to patrzysz, w kogo bardziej wierzysz.
Według JLS tak, jest . Zwłaszcza jeśli przeformułujesz pytanie na: „Czy
null
typ jest dosłownyObject
?”. Oprócz JLS 4.1 cytowanego powyżej przez Michaela Borgwardta:Zobacz JLS 3.10.7 :
i JLS 4.10 :
lub JLS 4.10.2 :
[Podkreśla przeze mnie.]
Według kompilatora Eclipse 2019-09 to nie jest :
Według OpenJDKs 12.0.1
javac
jest to :Gdzie nawiasy ostre sugerują, że
null
jest to inny typ niż pierwotny. I zgodnie z JLS 4.1 :jeśli to nie to, to jest drugie.
Claudiu napisał:
Au contraire,
null
jest piękna. Co zamiast tego sugerowałbyś jako wartość domyślną dla zmiennej typu referencyjnego? Dowolna kombinacja bitów? Witamy w naruszeniu dostępu lub, co gorsza, w piekle wskaźnikowym!Joachim Sauer napisał:
W rzeczywistości istnieją trzy elementy w połączeniu z wartością null (patrz także JLS 3.10.7 ):
null
Dosłowny .(1) Należy zauważyć, że zgodnie z cytowanym powyżej JLS 4.10.2 typ zerowy wykorzystuje wielokrotne dziedziczenie nie tylko dla interfejsów, ale także dla klas. Co wszyscy wiemy, nie jest możliwe dla nas, programistów aplikacji.
(2) Pusty literał można sobie wyobrazić jako zmienną zdefiniowaną jako:
JVM_global final null_type null = new null_type();
Zwróć też uwagę na JLS 3.9 :
O
null instanceof <any type>
Mając na uwadze JLS 4.10.2 („ typ null jest podtypem każdego typu”)
null instanceof <any type>
powinno się oceniaćtrue
, prawda? Na pierwszy rzut oka tak, ale JLS 15.20.2 daje wgląd w odpowiedź:[Podkreśla przeze mnie.]
Zadaj sobie pytanie, co ma większy sens (z punktu widzenia programisty aplikacji):
Podanie
false
i tym samym wskazanie, że wyrażenie referencyjne nie jest typem dla nas ujawnionym, tj. Wskazanie, że nie odwołuje się do niczego użytecznego dla naslub podając
true
, w ten sposób informując nas, że wyrażenie zwraca się do specjalnego odniesienia, odniesienia zerowego , odnoszącego się do "obiektu", nie wiemy, czy on w ogóle istnieje i który jest specjalnego typu null, który nie ma nazwy, nie jest wystawiony my, ale czy poprzez literał null podtyp jest dowolnego typu, w tym dziedziczenie wielokrotne i czy i tak ma być ignorowany? Rozważ także bardziej praktyczny przykład:Co również prowadzi do:
Dlaczego
instanceof
nie można powiedzieć czegoś onull
przedmiotowości we właściwy sposób ?Nazywa się
instanceof
niesameorsubtypeof
. Oznacza to, że porównujemy typ instancji z typem, a nie dwoma typami. Teraznull
oznacza: „Nie ma instancji”, a jeśli nie ma instancji, nie ma typu instancji. To oczywiste, że porównywanie niczego z czymś ma prowadzićfalse
.Lub w „bardziej” realnym przykładzie:
Jak podsumowuje Michael: „null jest naprawdę wyjątkowe”.
źródło
Nie, nie jest to instancja klasy ani klasy. To odniesienie do niczego.
Edycja : nie przeczytałem specyfikacji, więc powyższe może nie być w 100% dokładne.
źródło
Jak wyjaśniono w rozdziale 4.1 Rodzaje typów i wartości specyfikacji języka Java, null to typ, który ma jedną wartość, odwołanie zerowe (i jest reprezentowane przez literał
null
):Możesz jednak przeczytać o wzorcu obiektu zerowego (którego nie polecam). Zobacz C2 Wiki lub Wikipedia, aby uzyskać więcej informacji na temat tego wzorca.
źródło
Nie. Nawet gdyby tak było, jest bezużyteczne, ponieważ nie ma żadnych metod ani pól.
źródło
Nie, nie jest obiektem, ponieważ null instanceof Object zawsze zwróci false, również istnieje tylko jedna wartość null, a nie jedna dla każdej klasy.
źródło
null instanceof <anytype>
wrócifalse
.Zgodnie ze specyfikacją Java ,
źródło
Java obsługuje obiekty za pośrednictwem odwołań. Null to podział OO-ności Javy, ponieważ spada poniżej poziomu OO. Nie, to nie jest przedmiot, to WARTOŚĆ odniesienia. I nie ma to nic wspólnego z paradygmatami obiektów, ale odnosi się do hydrauliki Javy, która umożliwia tworzenie obiektów.
źródło
Czy null jest wystąpieniem
java.lang.Object
? Nie.Czy null jest obiektem ? zależy od definicji „ jest ”.
źródło
Pierwsza linia pokazuje
null
może być przypisana do typuObject
, ale druga linia zademonstruje, że z pewnością nie jestObject
i ostatecznie daje w wynikujava.lang.NullPointerException
źródło
Nie,
null
nie jest obiektem.Jest to typ referencyjny, a jego wartość nie odwołuje się do żadnego obiektu, więc nie ma reprezentacjinull
w pamięci.źródło
Object
, a nie obiekt (jak w przypadku typu ). A jeśli ktoś odpowiednio przeformułuje pytanie ...