Başlatılmamış nesne değişkeni ile Java'da null olarak başlatılmış nesne değişkeni arasındaki fark nedir


12

Aşağıdaki iki nesne değişkeni var

Date a;
Date b=null;

Kesinlikle hem 'a' hem de 'b' herhangi bir nesneye gönderme yapmaz.

Şimdi aşağıdaki ifadeyi çağırırsam

System.out.println(a.toString());

Derleme zamanı hatası olurken, aşağıdaki ifadeyi çağırırsam

System.out.println(b.toString());

Derleme zamanı hatası olmayacak, ancak çalışma zamanı hatası olacak. Bunun sebebi nedir ve null değeri temsil etmek için gerçekte 'b' de hangi değer saklanacaktır?


2
SO'da birçok kez sordu ve cevapladı: Yerel değişkenler neden Java'da başlatılmıyor? , Java'da başlatılmamış değişkenler ve üyeler ve bunlarla bağlantılı birçok soru
gnat

@gnat, "başlatılmamış" ve "boş" arasındaki farkla ilgili başka sorularınız mı var? Cevabın benzer olması, bunun yinelenen bir soru olduğu anlamına gelmez.
DougM

@DougM eminim, bahsettiğim ilk soruyu okudun mu? "Java tasarımcılarının yerel değişkenlere varsayılan değer verilmemesi gerektiğini düşünmesi için herhangi bir sebep var mıydı? (FWIW , sadece başka bir sitede olduğu için teknik olarak kopya olamaz )
gnat

1
Bu, "başlatılmamış" ve "sıfır olarak başlatılmış" arasındaki farkı ele almaz, yalnızca "değişkenler neden otomatik olarak sıfırdan başlatılmaz?" Aynı konu, biraz farklı bir soru.
DougM

2
@DougM bu adres yerel
tatarcık

Yanıtlar:


3

Thats çünkü yerel değişkenlerin durumu kendi kapsamında kontrol edilir

 // method/loop/if/try-catch etc...
 {
   Date d; // if it's not intialised in this scope then its not intialised  anywhere
 }

Alanlar için durum böyle değil

class Foo{
 Date d; // it could be intialised anywhere, so its out of control and java will set to null for you
}

Şimdi, bir değişkeni null olarak ayarlamak ve hemen kullanmak neden iyidir? belki bu bazen korkunç hatalara yol açan tarihsel bir hatadır

 {
  Date d = null;
  try{
  }catch{ // hide it here 
  }
  return d;
 } 

Şimdi semantik fark nedir?

Date d;

yalnızca türdeki bir nesneye işaret eden bir referans tutabilecek değişkeni bildirir Date, ancak

Date d= null; 

tam olarak aynıdır, ancak referans bu kez null değerine işaret eder, null herhangi bir referansa benzer, yerel bir işaretçinin boşluğunu alır, yani 32 bit makinelerde 4 bayt ve 64 bit makinelerde 8 bayt


Bu sadece bir saat önce yayınlanan önceki cevap yapılan ve açıklanan nokta tekrar gibi görünüyor
gnat

@gnat Yorumunuz için teşekkürler, ama bunun olduğunu sanmıyorum, şerefe
Sleiman Jneidi

Null değerinin aynı zamanda bellekte bir yerde saklanan bir nesne olduğunu mu ve null ile atanan tüm nesne değişkenlerinin bu null nesneyi işaret ettiğini mi kastediyorsunuz?
Harish_N

@ Harish.N hayır, ben söylemedim, onun bir referans değil, bir nesne
dedim

Verdiğiniz örnekte 'd' bir referanstır .. Date türündeki bir nesneye referanstır ... benzer şekilde null bir referanssa .. hangi nesneye atıfta bulunur ..?
Harish_N

19

Sınıf alanları için fark yoktur. Bunlar null0 sayısal değerler için ve nesneler, varsayılan olarak falseboolelerde için.

Yöntemlerde bildirilen değişkenler için - Java bunların başlatılmasını gerektirir. Bunların başlatılmaması, erişildiklerinde derleme zamanı hatasına neden olur.

Sebebi nedir? Sınıf alanları herhangi bir yöntemle değiştirilebilir. Herhangi bir sırayla yöntem çağrılır. Özel olmayan tüm alanlar, diğer sınıflar ve / veya bu sınıfı genişleten sınıflar tarafından değiştirilebilir. Bu nedenle, başlatılmamış bir değişkeni bildirmenin bir anlamı yoktur, çünkü birçok, birçok yerde atanabilir.

Ancak yöntemlerin içindeki değişkenler yereldir ve yalnızca yöntemin kendisinde değiştirilebilir. Dolayısıyla olası hataları işaret etmek hem mümkün hem de rasyoneldir. Ve derleyici bunu yapmaya çalışıyor. O takdirde bilir alan başlatılmadı istediğin bu asla, çünkü, bir hata gösterecektir. Emin değilseniz - bir uyarı verecektir, böylece emin olabilirsiniz.

public static class Test {
    Date a; // ok 
    Date b = null; // ok

    public void test() {
        Date c;
        Date d = null;

        System.out.println(a.toString());
        System.out.println(b.toString());
        System.out.println(c.toString()); // error
        System.out.println(d.toString()); // warning
    }
}
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.