Java'da null nedir?


252

Nedir null?

nullbir şey örneğidir?

Hangi sete nullait?

Hafızada nasıl temsil edilir?


yegor256. JLS'den null hakkında. "Null Literal. Null türü, ASCII karakterlerinden oluşan null literal null ile temsil edilen bir değere, null referansına sahiptir. Null bir literal her zaman null türündedir." Makaledeki noktalar hakkında. 'Değişken ve Eksik Nesneler' bir özelliktir. 'Yavaş Başarısızlık' tasarım gereğidir. 'Bilgisayar Düşüncesi ve Nesne Düşüncesi' sadece iki düşünme biçimidir. 'Belirsiz Semantik' çok öznel. 'Geçici Hata İşleme', hatalarla çalışan başka bir türdür. Null, iyi veya kötü olmamasının aksine, JLS'de belirtilen bir değişmez değer veya başka bir şeydir.
Oleksii Kyslytsyn

Yanıtlar:


310

Null herhangi bir şeyin örneği midir?

Hayır, hayır türü yoktur nullbir olduğunu instanceof.

15.20.2 Tip Karşılaştırma Operatörü instanceof

RelationalExpression:
    RelationalExpression instanceof ReferenceType

Çalışma zamanında instanceofoperatörün sonucu true, RelationalExpression değerinin olmaması nullve başvurunun a yükseltilmeden ReferenceType'a aktarılabilmesidir ClassCastException. Aksi takdirde sonuç olur false.

Bu araçlar, herhangi bir türü için Eve Rherhangi için E o, o == null, o instanceof Rher zaman false.


'Null' hangi kümeye aittir?

JLS 4.1 Tür ve Değer Çeşitleri

Ayrıca adı olmayan ifadenin türü olan özel bir null türü nullde vardır. Çünkü boş tipi adı yok, bir bir değişken bildirmek mümkün değildir boş için türü veya döküm için boş türü. nullReferans bir ifadesi tek olası değeri sıfır türü. nullReferans hep herhangi bir referans tipine dökülebilir. Uygulamada, programcı null tipini göz ardı edebilir ve sadece nullherhangi bir referans tipinde olabilecek özel bir değişmez gibi davranabilir .


Boş nedir?

Yukarıdaki JLS alıntısının söylediği gibi, pratikte bunun "herhangi bir referans türünde olabilecek sadece özel bir değişmez" olduğunu iddia edebilirsiniz.

Java'da null == null(bu diğer dillerde her zaman geçerli değildir). Sözleşme ile, o da bu özel mülkiyet (dan sahip olduğunu da unutmayın java.lang.Object):

public boolean equals(Object obj)

Olmayan herhangi bir için, nullbir referans değeri x, x.equals(null)gerektiği return false.

Ayrıca tüm referans türleri için varsayılan değerdir (bunlara sahip değişkenler için):

JLS 4.12.5 Değişkenlerin İlk Değerleri

  • Her sınıf değişkeni, örnek değişkeni veya dizi bileşeni , oluşturulduğunda varsayılan bir değerle başlatılır :
    • Tüm referans türleri için varsayılan değer şudur null.

Bunun nasıl kullanıldığı değişir. Bir alanın kullanılıncaya kadar başlangıç ​​değerine sahip olacağı , "gerçek" değerle (hesaplanması pahalı olabilir) değiştirildiği alanların tembel olarak başlatılması olarak adlandırılanları etkinleştirmek için kullanabilirsiniz null.

Başka kullanımları da var. Şuradan gerçek bir örnek alalım java.lang.System:

public static Console console()

Döndürür : Varsa, sistem konsolu null.

Bu çok yaygın bir kullanım örüntüsüdür: nullbir nesnenin varlığını belirtmek için kullanılır.

İşte bu sefer başka bir kullanım örneği java.io.BufferedReader:

public String readLine() throws IOException

Döndürür : StringSatır sonlandırma karakterlerini içermeyen veya nullakışın sonuna ulaşılmışsa , satırın içeriğini içeren A.

Yani, sonunda , sonunu belirtmek için a dönene kadar her satır için readLine()dönecekti . Bu, her satırı aşağıdaki gibi işlemenizi sağlar:instanceof Stringnull

String line;
while ((line = reader.readLine()) != null) {
   process(line);
}

API sonlandırma koşulu readLine()geri dönüşe bağlı olmayacak şekilde tasarlanabilir null, ancak bu tasarımın işleri özlü hale getirme avantajına sahip olduğu görülebilir. Boş satırlarda sorun olmadığına dikkat edin "" != null.

Bu sefer başka bir örnek daha alalım java.util.Map<K,V>:

V get(Object key)

Belirtilen anahtarın eşlendiği değeri veya nullbu harita anahtar için eşleme içermiyorsa döndürür .

Bu harita nulldeğerlere izin veriyorsa , dönüş değeri nullmutlaka haritanın anahtar için eşleme içermediğini göstermez; haritanın anahtarı açık bir şekilde eşlemesi de mümkündür null. containsKeyOperasyon bu iki durumu ayırt etmek için kullanılabilir.

Burada, kullanımın bir şeyi nasıl nullkarmaşıklaştırabileceğini görmeye başlıyoruz . İlk ifade, anahtar eşlenmezse nulldöndürüldüğünü belirtir . İkinci ifade anahtar eşlenen olsa bile söylüyor nullolabilir de iade edilmesi.

Buna karşılık, anahtarlara ve değerlere java.util.Hashtableizin vermeyerek işleri basitleştirir null; onun V get(Object key), geri dönüş ise null, açık bir şekilde önemli eşlenmemiş anlamına gelir.

API'ların geri kalanını okuyabilir ve nerede ve nasıl nullkullanıldığını bulabilirsiniz . Bunların her zaman en iyi uygulama örnekleri olmadığını unutmayın .

Genel olarak, nullaşağıdakileri belirtmek için özel bir değer olarak kullanılır:

  • Başlatılmamış durum
  • Fesih koşulu
  • Mevcut olmayan nesne
  • Bilinmeyen bir değer

Hafızada nasıl temsil edilir?

Java ile mi? Endişeniz yok. Ve bu en iyi şekilde korunur.


nulliyi bir şey?

Bu artık sınırda öznel. Bazı insanlar bunun nullönlenebilecek birçok programcı hatasına neden olduğunu söylüyor . Bazıları NullPointerException, Java gibi bir dilde , bunu kullanmanın iyi olduğunu söylüyor çünkü programcı hatalarında başarısız olursunuz. Bazı insanlar Boş nesne kalıbı vb. nullKullanmaktan kaçınırlar .

Bu kendi başına büyük bir konudur, bu yüzden en iyi başka bir soruya cevap olarak tartışılır.

Bunu nullkendisinin mucidinden gelen bir alıntıyla bitireceğim , CAR Hoare (quicksort şöhretinin):

Buna milyar dolarlık hatam diyorum. Bu buluş olarak nullbu anda 1965 referans, bir nesne-yönelimli dilde (Algol B) 'de referanslar için ilk kapsamlı tipi sistem tasarımı oldu. Amacım, derleyici tarafından otomatik olarak yapılan kontrollerle tüm referans kullanımlarının kesinlikle güvenli olmasını sağlamaktı. Ancak null, başvuruda bulunmak çok kolay olduğu için, bir referans koymak için ayarlanmaya karşı koyamadım . Bu, son kırk yılda muhtemelen milyar dolarlık ağrı ve hasara neden olan sayısız hataya, güvenlik açığına ve sistem çökmesine neden oldu.

Bu sunumun Video derin gider; önerilen bir saat.


5
NIL1960 yılında ve muhtemelen daha önce LISP (as ) 'de null referanslar vardı . Ama Hoare sanmıyorum gerçekten o alıntı null referanslar iddiası buluş çalışıyor.
Stephen C

7
Hoare, null referansların icadını talep etmeye çalışmıyor; sadece onları özellikle etkili bir yerde bulundurduğunu iddia ediyor. Java da dahil olmak üzere, Algol'dan ilham alan birçok dil vardır ve null referansların kullanımları kısmen Algol'dan esinlenilmiş veya kopyalanmış olsa bile, Hoare bunların maliyetini sorumlu tutmakta haklıdır. Bununla birlikte, tahmininin oldukça düşük olduğunu hissediyorum. Bir trilyon dolar gerçek maliyete daha yakın olabilir.
cjs

32

Null herhangi bir şeyin örneği midir?

Hayır. Bu yüzden tüm sınıflar için null instanceof Xgeri dönülecektir . ( Türü bir nesne türü olan bir değişkene atayabileceğiniz gerçeğine aldanmayın . Açıkçası, atama örtük bir tür dönüşümü içerir; aşağıya bakın.)falseXnull

'Null' hangi kümeye aittir?

Boş türün tek ve tek üyesidir, burada boş tür aşağıdaki gibi tanımlanır:

Msgstr "" "Ayrıca özel bir null türü, null ifadesinin türü olan ve adı yok. Null türünün adı olmadığından, null türünde bir değişken bildirmek veya null türüne yayın yapmak imkansızdır. başvuru, null türündeki bir ifadenin olası tek değeridir.Null referans her zaman herhangi bir referans türüne aktarılabilir.Uygulamada, programcı null türünü yok sayabilir ve yalnızca null değerinin yalnızca herhangi bir özel olabilir başvuru türü. " JLS 4.1

Boş nedir?

Yukarıyı görmek. Bazı bağlamlarda, null"nesne yok" veya "bilinmeyen" veya "kullanılamaz" olarak belirtilir, ancak bu anlamlar uygulamaya özgüdür.

Hafızada nasıl temsil edilir?

Bu, uygulamaya özeldir ve nullsaf bir Java programında temsilini göremezsiniz . (Ancak null, tüm Java uygulamalarında olmasa da çoğunda sıfır makine adresi / işaretçisi olarak gösterilir.)


14

Boş nedir?

Hiçbir şey değil.

Null herhangi bir şeyin örneği midir?

Hayır hiçbir şey olmadığı için hiçbir şeyin örneği olamaz.

Null hangi kümeye aittir?

Set yok

Hafızada nasıl temsil edilir?

Bazı referans noktaları şöyle ise:

Object o=new Object();

Yığın belleğinde, oluşturulan yeni nesneye bir alan atanmıştır. Ve o bellekteki atanmış alanı gösterecektir.

şimdi o=null;

Bu şimdi o nesnenin o hafıza alanını göstermeyeceği anlamına gelir.


1
"Şimdi o = null; Bu, şimdi o nesnenin bellek alanını işaret etmeyeceği anlamına gelir." Bence Çöp Toplama
JAVA'da böyle

9

Hayır, hiçbir şeyin örneği değil, örneği her zaman yanlış olacaktır.


7

Null anahtar sözcüğü, herhangi bir nesneye başvurmayan bir null başvurusunu temsil eden bir değişmez değerdir . null, başvuru türü değişkenlerin varsayılan değeridir.

Ayrıca belki bir göz atın

null: Java Sözlüğü


2
Bir anahtar kelime değil, gerçek bir kelime . Kalitesiz ve normatif olmayan alıntı.
Lorne Marquis

6

Null herhangi bir sınıfın örneği değildir.

Ancak, herhangi bir (nesne veya dizi) türündeki değişkenlere null atayabilirsiniz:

 // this is false   
 boolean nope = (null instanceof String);

 // but you can still use it as a String
 String x = null;
 "abc".startsWith(null);

6

Java'da null (tm)

C ve C ++ 'da, "NULL" başlık dosyasında tanımlanan ve aşağıdaki gibi bir değere sahip bir sabittir:

    0

veya:

    0L

veya:

    ((void*)0)

derleyici ve bellek modeli seçeneklerine bağlı olarak. NULL, kesinlikle C / C ++ 'ın bir parçası değildir.

Java'da (tm), "null" bir anahtar kelime değil, null türünün özel bir değişmezidir. Herhangi bir referans türüne, int veya boolean gibi ilkel türlere dökülemez. Boş değişmez değerin mutlaka sıfır değeri olması gerekmez. Ve null tipine dökmek veya bu tipte bir değişken bildirmek imkansızdır.


5

Bayt kodu gösterimi

Java'nın nulldoğrudan JVM desteği vardır: bunu uygulamak için üç talimat kullanılır:

  • aconst_null: örneğin bir değişkeni olduğu nullgibi ayarlamak içinObject o = null;
  • ifnullve ifnonnull: örneğin bir nesneyi olduğu nullgibi karşılaştırmak içinif (o == null)

Bölüm 6 "Java Sanal Makine Komut Seti" daha sonra nulldiğer talimatlar üzerindeki etkilerinden bahseder : NullPointerExceptionbirçoğu için bir atar .

2.4. "Referans Türleri ve Değerleri"null jenerik terimlerden de bahseder :

Bir referans değeri ayrıca, burada null ile gösterilecek olan özel null referans, hiçbir nesneye referans olabilir. Null başvurusu başlangıçta çalışma zamanı türüne sahip değildir, ancak herhangi bir tür için kullanılabilir. Bir başvuru türünün varsayılan değeri null şeklindedir.


4

nullözel bir değerdir, hiçbir şeyin örneği değildir. Açıkçası bir instanceofşey olamaz .


3

nullherhangi bir sınıfın örneği olmayan özel bir değerdir. Bu, aşağıdaki program tarafından gösterilmiştir:

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);
   }
}

6
Örneğin gösterdiği tek şey bunun nullbir örneği olmamasıdır String.
Sasha Chedygov

4
İmzayı olarak değiştirirseniz, void f(String o)daha anlamlı olur.
Thilo

2

Java'daki null, C ++ 'daki nullptr işlevine benzer / buna benzer.

C ++ 'da Program:

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;
}

Java ile aynı program:

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");
        }
    }
}

Şimdi yukarıdaki kodlardan Java'da null olanı anlıyor musunuz? Hayır ise, C / C ++ 'da işaretçiler öğrenmenizi öneririm ve sonra anlayacaksınız.

C ++ 'da, C ++' dan farklı olarak, nullptr tanımsızdır, ancak bunun yerine C + 'da da kullanılabilen NULL kullanılır, ancak C ++' da nullptr sadece NULL'dan daha fazla tercih edilir, çünkü C'deki NULL her zaman işaretçilerle ilişkilidir ve bu bu nedenle, C ++ 'da "ptr" soneki sözcüğün sonuna eklenmiştir ve ayrıca tüm harfler artık küçük harftir, ancak bu daha az önemlidir.

Java'da, ilkel olmayan tip sınıfının her değişkeni her zaman bu türün nesnesine başvurur veya devralınır ve null, null sınıf nesnesi başvurusudur, ancak null işaretçi değildir, çünkü Java'da böyle bir şey "pointer" yoktur, ancak sınıfa başvurur Bunun yerine nesneler kullanılır ve Java'daki null, sınıf nesnesi başvurularıyla ilişkilidir, bu nedenle "nullref" veya "nullrefobj" olarak da adlandırılabilir, ancak bu uzun, bu nedenle "null" olarak adlandırın.

C ++ 'da isteğe bağlı üyeler / değişkenler için işaretçiler ve nullptr değeri kullanabilirsiniz , yani değeri olmayan üye / değişken ve değeri yoksa nullptr değerine eşittir, böylece Java'da null kullanılabilir.


1

Java'da iki ana tür kategori vardır: ilkel ve referans . İlkel tipte depolanmış değerler olarak beyan edilen değişkenler; başvuru türü bildirilen değişkenler başvuruları depolar.

String x = null;

Bu durumda, başlatma deyimi “x” değişkenlerini bildirir. “X” String referansını saklar. Burada boş . Her şeyden önce, null geçerli bir nesne örneği değildir, bu nedenle bunun için ayrılan bellek yoktur. Basitçe, nesne referansının şu anda bir nesneye gönderme yapmadığını gösteren bir değerdir.


0

Benim görüşüme göre Java null null görmek için ilginç bir yolu, bunu bir bilgi eksikliğini değil SADECE herhangi bir tür referans atanabilir gerçek bir değer olarak görmek bir şey olarak görmek. Herhangi bir bilginin yokluğunu belirtiyorsa bunu düşünürseniz, a1 == a2'nin doğru olması anlamlı değildir (her ikisine de boş değer atanmış olmaları durumunda), gerçekten HERHANGİ BİR nesneye işaret edebilecekleri için (basitçe hangi nesnelere işaret etmeleri gerektiğini bilmiyorum) ... Bu arada null == null java'da true değerini döndürür. Java örneğin SQL: 1999 gibi olursa, null == null bilinmeyen döndürür (SQL: 1999'daki bir boole değeri üç değer alabilir: true, false ve unknown, ancak uygulamada bilinmeyen gerçek sistemlerde null olarak uygulanır) ... http://en.wikipedia.org/wiki/SQL


0

Tüm sorularınızı resmi olarak JLS'den cevaplayan kısa ve kesin cevap:

3.10.7. Sıfır Değişmez

Null türü, ASCII karakterlerinden oluşan null değişmez null ile temsil edilen bir değere, null referansına sahiptir.

Null değişmez değeri daima null türündedir.

Yalnızca null değerine atanan türde bir başvuru ayrılır. Referansa herhangi bir değer (nesne) atamazsınız. Bu tahsis JVM'ye ne kadar referans alacağı ve hangi bellek alanına tahsis edileceğine özgüdür.

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.