Null bir Nesne mi?


119

ObjectJava'da null an mı ?


41
Hayır değil ve neden böyle bir sorunun olduğunu merak edenler için, null'un gerçekten de herhangi bir nesne gibi bir nesne olduğu diller vardır, örneğin Ruby.
JRL

7
Tipler konusunda oldukça titiz davranan Scala'da tek örneği olan bir tip Null( aslında bir özellik ) vardır null.
Carl Smotricz

1
@JRL: Sadece merak ettiğim için, bunun JRuby'nin nasıl çalıştığını nasıl etkilediğini merak ediyorum ... (Emin olmak için bu uygulama düzeyine yeterince aşina değilim.)
Benjamin Oakes

JRL yorumuna @ eklemek için - Ruby'nin pürüzlü eşdeğer kadar nullolan nilbir örneğidir ki, NilClass
Eliot Sykes

Veya null instanceof Objectyanlış olan ancak typeof(null)geri dönen javascript 'object'. Bu durumda bir nesne mi? Kim bilir.
Don Hatch

Yanıtlar:


166

Null bir Object olsaydı, java.lang.Objectgibi yöntemleri desteklerdi equals(). Ancak, durum böyle değildir - bir boş değerdeki herhangi bir yöntem çağrısı, bir NullPointerException.

Ve bu, Java Dil Spesifikasyonunun bu konuda söylediği şey:

Ayrıca, adı olmayan null ifadesinin türü olan özel bir boş tür vardır. Boş tipin adı olmadığı için, boş tipte bir değişken bildirmek veya boş tipe dönüştürmek imkansızdır. Boş başvuru, boş tipteki bir ifadenin olası tek değeridir. Boş başvuru her zaman herhangi bir başvuru türüne dönüştürülebilir. Uygulamada, programcı boş türü görmezden gelebilir ve null'ın yalnızca herhangi bir referans türünde olabilen özel bir değişmez değer olduğunu varsayabilir.

Sanırım bu, "boş özeldir" olarak özetlenebilir.


1
Yani Java'daki bir nesne, yalnızca alt sınıflara eşitse bir nesnedir java.lang.Object. Pratik olarak - evet. Java.lang.Object'in alt sınıfı olmayan bir sınıf oluşturamazsınız, ancak daha felsefi bir bakış açısıyla düşünmedim
Andreas Dolk

Merakla, her şeyden önce, API dokümanıNullPointerException bir » nullnesneden« söz ediyor … :) Ama sonra, »boş işaretçilerden« bahsetmek de uygun oldu…
Lumi

"Boş referans her zaman herhangi bir referans türüne dönüştürülebilir" dediniz. Öyleyse, nesne başvurusu (dönüş) türü olan bir yöntemde null (typecasted-izin verilirse) döndürebilir miyiz?
Srichakradhar

1
@Srichakradhar: evet, yapabiliriz! Burada sormaktansa kodla deneyerek daha kolay öğrenebilirsiniz.
Michael Borgwardt

1
"Boş başvuru, boş tipteki bir ifadenin olası tek değeridir". Özellikler belgesini okumanın zamanı geldi. :)
sofs1

32

Java spesifikasyonuna göre , nullbir nesne değişkenine atanabilen bir türdür (yorumda belirtildiği gibi bir değer olarak). Bu türden değişkenleri örnekleyemez veya oluşturamazsınız, ancak nullderleyici tarafından sağlanan değişmezi kullanmanız gerekir .


8
null bir tür ve değerdir.
Joachim Sauer

5
nullAdı bir "örneği" dir nullgörünüşe göre, tip.
strager

nullbir değişken değil , birebirdir
Gerold Broser

Re " nullatanabilen bir türdür ": 1) null(kodda) boş değerdir , boş tür değil 2) Tipler genel olarak Java'da değişkenlere atanamaz, bkz. JLS 4.1: " [... ] [...] değişkenlerinde saklanabilen iki tür veri değeri: ilkel değerler (§4.2) ve referans değerleri (§4.3). " Değişken aracılığıyla atanabilen boş referanstırnull . ... devamı ...
Gerold Broser

3) nesne "olarak nesne değişkeni sınıf değişkenine göre", genellikle türüne ama kullanım ömrü ile ilgili değildir. Türe atıfta bulunurken genellikle bir referans türünün değişkeni veya kısaca referans (tür) değişkeni olarak adlandırılır. Java API'sinde örnek / nesne değişkenlerini açığa çıkaran 4 türün farkındayım (daha fazlası olabilir): onunlength ve alt sınıflarını içeren dizilerjava.awt.geom.Point2D .
Gerold Broser



12

Null, bir nesnenin olmamasıdır.


Ancak boş tür, her başvuru türüne atanabilir.
Tom Hawtin - tackline

"Boş tip" yoktur; null, ilkel olmayan ifadelerin belirli bir değeridir (yani referanslar; anladığım kadarıyla Java'da da "başvuru türü" yoktur).
Tommy McGuire

3
Tommy: JLS 4.1: "Ayrıca, adı olmayan null ifadesinin türü olan özel bir boş tip var."
Ken


12

JRL şunu yazdı:

Hayır değil, ...

Sıklıkla, nereye baktığınıza, kime daha çok inandığınıza bağlıdır.

JLS'ye göre evet, öyle . Özellikle soruyu şu şekilde yeniden ifade ederseniz: " nullYazı tipi Objectmi?". Yukarıda Michael Borgwardt tarafından alıntılanan JLS 4.1'e ek olarak :

Bkz. JLS 3.10.7 :

Boş bir değişmez değer her zaman boş türdendir.

ve JLS 4.10 :

T türünün alt türlerinin tümü U türleridir, öyle ki T, U'nun bir süper türü ve boş türdür.

veya JLS 4.10.2 :

Null türünün doğrudan süper türleri , boş türün kendisi dışındaki tüm başvuru türleridir .

[Benim tarafımdan vurgular.]

Eclipse 2019-09'un derleyicisine göre şu değil :

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

OpenJDKs göre 12.0.1 javac öyle :

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

Köşeli parantezlerin nullbunun ilkel bir türden farklı olduğunu ima ettiği yerde. Ve JLS 4.1'e göre :

Java programlama dilinde iki tür tür vardır: ilkel türler (...) ve başvuru türleri (...).

eğer biri değilse, diğeri.


Claudiu şunu yazdı:

null biraz çirkin.

Au contraire, nullgüzeldir. Bunun yerine bir referans türü değişkeni için varsayılan değer olarak ne önerirsiniz? Keyfi bit kombinasyonu? Erişim ihlaline veya daha da kötüsü işaretçi cehennemine hoş geldiniz!


Joachim Sauer şunu yazdı:

null bir tür ve değerdir.

Aslında null ile bağlantılı üç öğe vardır (ayrıca bkz. JLS 3.10.7 ):

  1. (Aksi takdirde adlandırılmamış) boş tür .
  2. null Değişmezi .
  3. Null başvuru değer. (Genellikle boş değer veya sadece boş olarak kısaltılır .)

(1) Yukarıda belirtilen JLS 4.10.2'ye göre , boş tipin yalnızca arayüzler için değil sınıflar için de çoklu kalıtım kullandığına dikkat edin. Hepimizin bildiği gibi uygulama programcıları için mümkün değildir.

(2) Boş değişmez , şu şekilde tanımlanan bir değişken olarak düşünülebilir:

JVM_global final null_type null = new null_type();

Ayrıca JLS 3.9'a dikkat edin :

Çeşitli karakter dizilerinin bazen yanlış bir şekilde anahtar kelime olduğu varsayılır:

  • nullbir anahtar kelime değil, boş değişmezdir ( §3.10.7 ).

ilişkin null instanceof <any type>

JLS 4.10.2 akılda tutularak (" boş tip, her türden bir alt tiptir") null instanceof <any type>değerlendirilmeli true, değil mi? İlk bakışta evet, ancak JLS 15.20.2 içgörü cevabını veriyor:

[...] sonuç ait instanceofoperatörü olan truedeğeri ise bir RelationalExpression değilnull [...]. Aksi takdirde sonuç olurfalse .

[Benim tarafımdan vurgular.]

Kendinize neyin daha mantıklı olduğunu sorun (bir uygulama programcısının bakış açısından):

  • Verilmesi falseve böylece bir referans ifadesi bize maruz bir tür olmadığını belirten bize yararlı bir şey başvuran değil belirten yani

  • ya da truebize ifadenin özel bir referansa göre değerlendirildiğini bildiren boş referans , var olup olmadığını bilmediğimiz ve adı olmayan özel boş tipte olan bir "nesneye" atıfta bulunur , maruz kalmaz. bize ancak boş literal aracılığıyla, çoklu kalıtım içeren herhangi bir türden bir alt tür midir ve yine de göz ardı edilmelidir? Daha pratik bir örneği de düşünün:

     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.

Bu da şunlara yol açar:

Neden Nesnesi instanceofhakkında bir şeyler söylemenin uygun bir yolu değil null?

instanceofDeğil denir sameorsubtypeof. Bu, bir örneğin türünü iki türle değil, bir türle karşılaştırdığımız anlamına gelir. Şimdi şu nullanlama gelir: "Örnek yoktur" ve örnek yoksa, örneğin türü yoktur. Hiçbir şeyi bir şeyle karşılaştırmanın yol açacağı açık false.

Veya "daha" gerçek dünya örneğinde:

  • Elimde üzerinde »Big Apple« ( = referans türü adı ) yazan gerçek boyutta bir elma resmi var ( = referans türü ) .
  • Önümde bir masa ( = yığın ) var.
  • Tabloda bir elma ( = örnek ) varsa ona bağlı bir kordon ( = referans ) vardır.
  • Bu kablonun diğer ucunu elimde tutuyorum ( = referans değişken ).
  • Elmayı kordon boyunca izlerim ve resmimle karşılaştırırım ( = instanceof ).
  • Elma resimle aynı büyüklükte veya daha büyükse, »Big Apple« yazısı ona uygulanır ( = true ).
  • Daha küçükse, o zaman değil ( = yanlış ).
  • Tabloda elma yoksa (= örnek yoksa ) ve dolayısıyla kordon yoksa ( = boş ) yazı da geçerli olmaz ( = yanlış ). Çünkü: Hiçbir elma büyük bir elma değil mi? Hayır değil.


Michael'ın özetlediği gibi: "boş değer özeldir".


2
Apple ve null? Bir davadan korkmuyor musun? :)
Gábor Lipták

9

Hayır, bu bir Sınıfın veya Sınıfın bir örneği değildir. Hiçbir şeye gönderme yapıyor.

Düzenleme : Spesifikasyonu okumadınız, bu nedenle yukarıdakiler% 100 doğru olmayabilir.


5

Bölüm 4.1 Java Dil Spesifikasyonunun Türleri ve Değerleri bölümünde açıklandığı gibi , null, tek bir değere sahip bir türdür, boş referans (ve değişmez değerle temsil edilir null):

İfadenin adı olmayan özel bir boş tip nullde vardır. Boş tipin adı olmadığı için, boş tipte bir değişken bildirmek veya boş tipe dönüştürmek imkansızdır. Boş başvuru, boş tipteki bir ifadenin olası tek değeridir. Boş başvuru her zaman herhangi bir başvuru türüne dönüştürülebilir. Uygulamada, programcı boş türü görmezden gelebilir ve sadece nullherhangi bir referans türünde olabilen özel bir değişmez değermiş gibi davranabilir .

Yine de (benim önermediğim) Boş Nesne Kalıbı hakkında okumak isteyebilirsiniz . Bu kalıp hakkında daha fazla bilgi için C2 Wiki veya Wikipedia'ya bakın.



4

Hayır, bir nesne değildir, çünkü null nesnesi her zaman yanlış döndürür, ayrıca her sınıf için bir tane değil, yalnızca bir boş değer vardır.


3
Aslında null instanceof <anytype>geri dönecek false.
Bombe

4

Göre Java Spec ,

Ayrıca, herhangi bir başvuru türü için bir değer olarak kullanılabilecek özel bir boş hazır bilgi de vardır. null, ilkel türlerin değişkenleri dışında herhangi bir değişkene atanabilir. Varlığını test etmenin ötesinde boş bir değerle yapabileceğiniz çok az şey var. Bu nedenle, null genellikle programlarda bazı nesnelerin kullanılamaz olduğunu belirtmek için bir işaretçi olarak kullanılır.


4

Java, nesneleri referanslar yoluyla işler. Null, sizi OO seviyesinin altına düşürdüğü için Java'nın OO -luğunun bir dökümüdür. Hayır, bir nesne değil, referansın DEĞERİ. Ve nesne paradigmalarıyla hiçbir ilgisi yoktur, ancak nesneleri etkinleştiren Java tesisatıyla ilgilidir.


3

Null bir örneği java.lang.Objectmi? Hayır.

Null bir nesne mi? " eşittir " tanımına bağlıdır .


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

İlk satır şovları nullyazıya atanabilir Object, ancak ikinci satır bunun kesinlikle bir olmadığını gösterecek Objectve sonunda birjava.lang.NullPointerException


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.