Java - Nedir bu NullPointerException?

javabey

git add Brain.java in/earth/people/brainless
En iyi cevaplar
0
Konu ile alakasız mesaj.
aman çok şey biliyorum, o terim benim şu terim senin
 

LifeMCServer

Nether Yerlisi
En iyi cevaplar
98
Birisi şunu yapmayın deyip nedenini açıklarsa niye yapasın o şeyi :(


Ben ortada "null kullanmayın hatalardan kurtulun, null is evil moruk" dışında mantıklı bir açıklama göremiyorum, nedenini nerede nasıl mantıklı olarak açıklamış?

Bunların hiç birisi bana mantıklı gelmiyor:

"Javaya sadece insanlar alıştığı için eklendi", "Yapımcısı bile sevmiyor", "Tamamen çöp gereksiz çöpten farkı yok", "Hatalara ve buglara sebep oluyor", "Kullanmayın kullandırtmayın"

Yukarıda da yazdığım gibi bunların hepsi sadece sizin görüşünüzdür. İnsanlara tavsiye verebilirsiniz fakat bunu kesin konuşarak yapar iseniz o tavsiyeden çok "evrensel herkesin kabul ettiği" bir şeymiş gibi gözükür ve isteyen herkes itiraz edebilir. Hem kesin konuşuluyor, hem de direk bir şeyi yok etmek hedefleniyor, yanlış veya doğru kullanımları anlatılarak objektif bir şey yapmak yerine "tamamen kötü, kullanmayın, bir de üstüne kullandırtmayın" deniyor.
 

GodofMilker

Nether Yerlisi
En iyi cevaplar
0
Ben ortada "null kullanmayın hatalardan kurtulun, null is evil moruk" dışında mantıklı bir açıklama göremiyorum, nedenini nerede nasıl mantıklı olarak açıklamış?

Bunların hiç birisi bana mantıklı gelmiyor:

"Javaya sadece insanlar alıştığı için eklendi", "Yapımcısı bile sevmiyor", "Tamamen çöp gereksiz çöpten farkı yok", "Hatalara ve buglara sebep oluyor", "Kullanmayın kullandırtmayın"

Yukarıda da yazdığım gibi bunların hepsi sadece sizin görüşünüzdür. İnsanlara tavsiye verebilirsiniz fakat bunu kesin konuşarak yapar iseniz o tavsiyeden çok "evrensel herkesin kabul ettiği" bir şeymiş gibi gözükür ve isteyen herkes itiraz edebilir. Hem kesin konuşuluyor, hem de direk bir şeyi yok etmek hedefleniyor, yanlış veya doğru kullanımları anlatılarak objektif bir şey yapmak yerine "tamamen kötü, kullanmayın, bir de üstüne kullandırtmayın" deniyor.
Peki ben null hakkında bir şey dedim mi :(
 

Whoisthatinblack

Taş Madencisi
En iyi cevaplar
0
Ben ortada "null kullanmayın hatalardan kurtulun, null is evil moruk" dışında mantıklı bir açıklama göremiyorum, nedenini nerede nasıl mantıklı olarak açıklamış?

Bunların hiç birisi bana mantıklı gelmiyor:

"Javaya sadece insanlar alıştığı için eklendi", "Yapımcısı bile sevmiyor", "Tamamen çöp gereksiz çöpten farkı yok", "Hatalara ve buglara sebep oluyor", "Kullanmayın kullandırtmayın"

Yukarıda da yazdığım gibi bunların hepsi sadece sizin görüşünüzdür. İnsanlara tavsiye verebilirsiniz fakat bunu kesin konuşarak yapar iseniz o tavsiyeden çok "evrensel herkesin kabul ettiği" bir şeymiş gibi gözükür ve isteyen herkes itiraz edebilir. Hem kesin konuşuluyor, hem de direk bir şeyi yok etmek hedefleniyor, yanlış veya doğru kullanımları anlatılarak objektif bir şey yapmak yerine "tamamen kötü, kullanmayın, bir de üstüne kullandırtmayın" deniyor.

Tony Hoare'nin yukarıda paylaşılmış makalesi tek başına yeterli bi' argüman aslında ama ben yine de sana anlatmaya çalışayım.

Varsayalım ki önemli bir proje üzerinde çalışıyoruz. Her yerde null kullanılmış ve kodu yazan kişi elinden geldiğince null kontrolü yapmış. Fakat... Ya null olamayacağını düşündüğü bir değişken null olursa? Yazdığı kod productionda çalışırken ve belki de çok kritik bir işlevi varken bir npe ile patlaması tolere edilebilir bir şey midir? Hiç null kullanmamış olsa mışıl mışıl çalışacak programını null ile zehirlemesi neden?

Ayrıca büyük codebaselerde yeteri kadar test yazılmamışsa (ki tdd mantığı ile çalışılmıyorsa genellikle yazılmaz) programın hızlı debug edilebilmesi gerekir. Böyle büyük codebaselerde bir npe ile karşılaşıldığında nereden geldiğini bulmaya çalışmak çoğu zaman samanlıkta iğne aramaya benzer. Özellikle bir başkasının yazmış olduğu codebase sonradan sana devredilmişse ve npe ile karşılaşmışsan, değerli vaktinin uzunca bir bölümünü debug ile harcayacaksın demektir.

Yukarıda belirtilen sebeplerden ötürüdür ki, null kullanmaktan elimizden geldiğince kaçınmalıyız. Java 8 ve sonrasında null'e alternatif olarak
Linki görebilmek için üye olmanız gerekiyor. Giriş yap veya üye ol.
eklenmiştir, tavsiye ederim. Ve hayır, null'ün doğru herhangi bir kullanımı yoktur. Olduğunu düşünen her kimse burada paylaşırsa doğru olmadığını gösterebilirim.

Son olarak; burada belirttiklerim benim görüşüm değil, dünya genelindeki tüm programcıların ortak düşünceleri ve deneyimleri sonucu oluşmuş argümanlardır. Benim verdiğim cevabın aynısını benden kat ve kat daha önemli ve bilgili insanlar da vermektedir.
 

LifeMCServer

Nether Yerlisi
En iyi cevaplar
98
Tony Hoare'nin yukarıda paylaşılmış makalesi tek başına yeterli bi' argüman aslında ama ben yine de sana anlatmaya çalışayım.

Varsayalım ki önemli bir proje üzerinde çalışıyoruz. Her yerde null kullanılmış ve kodu yazan kişi elinden geldiğince null kontrolü yapmış. Fakat... Ya null olamayacağını düşündüğü bir değişken null olursa? Yazdığı kod productionda çalışırken ve belki de çok kritik bir işlevi varken bir npe ile patlaması tolere edilebilir bir şey midir? Hiç null kullanmamış olsa mışıl mışıl çalışacak programını null ile zehirlemesi neden?

Ayrıca büyük codebaselerde yeteri kadar test yazılmamışsa (ki tdd mantığı ile çalışılmıyorsa genellikle yazılmaz) programın hızlı debug edilebilmesi gerekir. Böyle büyük codebaselerde bir npe ile karşılaşıldığında nereden geldiğini bulmaya çalışmak çoğu zaman samanlıkta iğne aramaya benzer. Özellikle bir başkasının yazmış olduğu codebase sonradan sana devredilmişse ve npe ile karşılaşmışsan, değerli vaktinin uzunca bir bölümünü debug ile harcayacaksın demektir.

Yukarıda belirtilen sebeplerden ötürüdür ki, null kullanmaktan elimizden geldiğince kaçınmalıyız. Java 8 ve sonrasında null'e alternatif olarak
Linki görebilmek için üye olmanız gerekiyor. Giriş yap veya üye ol.
eklenmiştir, tavsiye ederim. Ve hayır, null'ün doğru herhangi bir kullanımı yoktur. Olduğunu düşünen her kimse burada paylaşırsa doğru olmadığını gösterebilirim.

Son olarak; burada belirttiklerim benim görüşüm değil, dünya genelindeki tüm programcıların ortak düşünceleri ve deneyimleri sonucu oluşmuş argümanlardır. Benim verdiğim cevabın aynısını benden kat ve kat daha önemli ve bilgili insanlar da vermektedir.

"Ya null olamayacağını düşündüğü bir değişken null olursa? Yazdığı kod productionda çalışırken ve belki de çok kritik bir işlevi varken bir npe ile patlaması tolere edilebilir bir şey midir? Hiç null kullanmamış olsa mışıl mışıl çalışacak programını null ile zehirlemesi neden?"

Null olamayacağını düşündüğü bir değişken null oluyor ise bu onun hatasıdır. Yeteri kadar test / debugging yapmamıştır. Hiç null kullanılmayan aynı program nasıl mışıl mışıl çalışacak? "Null olamayacağını düşündüğün" bir variable null ise bu senin hatandır. Null kullanmamak sadece oradaki hatayı gizler.

Mesela null yerine 0, boş string gibi default değerler kullandın bu durumda hata yemezsin fakat daha sonra "neden sürekli varsayılan değer oluyor / false döndürüyor" gibi düşünüp durursun (kaldı ki sonradan her türlü değişecek olan bir variableye default değer vermek gereksiz, null vermez isen de variable not initialized hatası alabilirsin).

Kısaca NPE kötü bir şey değil, null öyle mi orası tartışılır fakat çıkıpta "dünya genelindeki tüm programcıların ortak düşünceleri ve deneyimleri bu yönde" demen yanlış olur. Yine önceden dediğim konu geçerli burada.

NPE bir bugu hata verdirerek gözümüze sokar. NPE'yi susturmak, catchlemek, veya varsayılan değerler kullanmak bana göre (belki de dünya üzerindeki pardon genelindeki TÜM programcıların ortak görüşüne göre değil, evet, bana göre) mantıksızdır.

Eğer Kotlin'den veya başka bir dilden bahsediyor olsaydık belkide dediğiniz biraz daha doğru olurdu fakat Java'da nullable type olayı yok ve her şey null olabilir (optional kullanılabilir dediğin gibi fakat direk dil desteği yok), sen null kullanmasan bile eğer NPE istemiyorsan dış değerleri her zaman null check ile kontrol etmelisin.

Ben yinede her zaman gerekli önlemleri alırım fakat kendi iç kodumda null olamayacak bir şeyin null olupta NPE vermesi benim karşı olduğum bir durum değildir, aksine NPE vermesi hatayı / bugu daha kolay tespit etmemi sağlar.

Son olarak diyeceğim şu ki bir şeyin varlığını yok sayamazsınız, null kullanmasanız da Java'da null vardır, NPE vermese de orada bir bug vardır. Programınızda hata çıkması sizi bu kadar endişelendiriyor ise tüm kodunuzu try catch içine alıp Throwable catchleyerek hepsini yok sayınız (!)

Hatta uncaught exception handler'ı da ignorelayacak şekilde ayarlayınız, bununla alakalı bir diğer konum vardı ister iseniz orayı da bu şekilde tartışmalar ile kirletebiliriz, benim için problem değil.
 

Whoisthatinblack

Taş Madencisi
En iyi cevaplar
0
"Ya null olamayacağını düşündüğü bir değişken null olursa? Yazdığı kod productionda çalışırken ve belki de çok kritik bir işlevi varken bir npe ile patlaması tolere edilebilir bir şey midir? Hiç null kullanmamış olsa mışıl mışıl çalışacak programını null ile zehirlemesi neden?"

Null olamayacağını düşündüğü bir değişken null oluyor ise bu onun hatasıdır. Yeteri kadar test / debugging yapmamıştır. Hiç null kullanılmayan aynı program nasıl mışıl mışıl çalışacak? "Null olamayacağını düşündüğün" bir variable null ise bu senin hatandır. Null kullanmamak sadece oradaki hatayı gizler.

Mesela null yerine 0, boş string gibi default değerler kullandın bu durumda hata yemezsin fakat daha sonra "neden sürekli varsayılan değer oluyor / false döndürüyor" gibi düşünüp durursun (kaldı ki sonradan her türlü değişecek olan bir variableye default değer vermek gereksiz, null vermez isen de variable not initialized hatası alabilirsin).

Kısaca NPE kötü bir şey değil, null öyle mi orası tartışılır fakat çıkıpta "dünya genelindeki tüm programcıların ortak düşünceleri ve deneyimleri bu yönde" demen yanlış olur. Yine önceden dediğim konu geçerli burada.

NPE bir bugu hata verdirerek gözümüze sokar. NPE'yi susturmak, catchlemek, veya varsayılan değerler kullanmak bana göre (belki de dünya üzerindeki pardon genelindeki TÜM programcıların ortak görüşüne göre değil, evet, bana göre) mantıksızdır.

Eğer Kotlin'den veya başka bir dilden bahsediyor olsaydık belkide dediğiniz biraz daha doğru olurdu fakat Java'da nullable type olayı yok ve her şey null olabilir (optional kullanılabilir dediğin gibi fakat direk dil desteği yok), sen null kullanmasan bile eğer NPE istemiyorsan dış değerleri her zaman null check ile kontrol etmelisin.

Ben yinede her zaman gerekli önlemleri alırım fakat kendi iç kodumda null olamayacak bir şeyin null olupta NPE vermesi benim karşı olduğum bir durum değildir, aksine NPE vermesi hatayı / bugu daha kolay tespit etmemi sağlar.

Son olarak diyeceğim şu ki bir şeyin varlığını yok sayamazsınız, null kullanmasanız da Java'da null vardır, NPE vermese de orada bir bug vardır. Programınızda hata çıkması sizi bu kadar endişelendiriyor ise tüm kodunuzu try catch içine alıp Throwable catchleyerek hepsini yok sayınız (!)

Hatta uncaught exception handler'ı da ignorelayacak şekilde ayarlayınız, bununla alakalı bir diğer konum vardı ister iseniz orayı da bu şekilde tartışmalar ile kirletebiliriz, benim için problem değil.

Null olamayacağını düşündüğü bir değişken null oluyor ise bu onun hatasıdır.
Bu mantıkla düşünürsek, bizim gözümüzden kaçan hiçbir null olmamalı ve buna bağlı olarak hiç npe görmemeliyiz. Eğer ki sen ve beraber çalıştığın insanlar bu kadar kusursuzsa söyleyebileceğim bir şey yok, zaten npe görmüyorsunuz ne mutlu size. Fakat null kullanıyor ve npe lerle karşılaşıyorsan iş değişir. Zira null olamayacağını düşündüğün fakat null olan bir değişken olmazsa npe de olmaz.

Öte yandan null yerine varsayılan bir değer veya bir "null objesi" döndürdüğünde hatayı gizlemiş falan olmazsın. Bir metot, içerisinde istenen elementlerin bulunduğu dolu bir liste yerine boş bir liste döndürdüğünde, program dolu liste ile yapacağı şeyi boş liste ile de yapabilir. Eğer ki program beklendiği gibi çalışmıyorsa sıkıntının dönen bu liste olduğunu anlayabilmek, programın ölmesine sebep olan npe nin kaynağını bulabilmekten çok daha kolay ve çabuktur. "null objesi"ne aşağıda değineceğim.

fakat çıkıpta "dünya genelindeki tüm programcıların ortak düşünceleri ve deneyimleri bu yönde" demen yanlış olur
Söylediğim söz yanlış değil çünkü dünya genelindeki büyük yazılım firmaları özellikle null kullanımını yasaklarlar. Çalışanlarının null kullanmasına izin vermeyerek müşterilerine teslim ettikleri programların npe sebebiyle crash yemesini engellerler. Sen hiç önemli bir Android uygulamasının npe ile çöktüğünü gördün mü? Ek olarak tanınan ve bilinen birçok önemli ismin de bu konuda makaleleri mevcuttur.

optional kullanılabilir dediğin gibi fakat direk dil desteği yok
Optional dilin kendisinde olan bir şey zaten????

sen null kullanmasan bile eğer NPE istemiyorsan dış değerleri her zaman null check ile kontrol etmelisin.
Eğer ki bağımlı olduğun bir kütüphanenin bir metotunun null döndürebilme olasılığı varsa maalesef null kontrolü yapmak zorundasın. Fakat bu senin değil, kütüphanenin problemidir ve bununla pek sık karşılaşılmaz.

kendi iç kodumda null olamayacak bir şeyin null olupta NPE vermesi benim karşı olduğum bir durum değildir
Program en ufak bir yanlış çalışma halinde npe vererek sonlanırsa, programı kullanmaya çalışan kişi veya kişiler ne yapacaklar? Mesela Whatsapp'ın son sürümünde senin hiç kullanmadığın bir özellik sıkıntılı olsa ve sen sırf bunun yüzünden arkadaşlarınla haberleşemesen ne olur? Peki ya tüm uygulamanın npe yüzünden sonlandırılması yerine sadece hatalı olan o özellik kullanılamaz olsa?

aksine NPE vermesi hatayı / bugu daha kolay tespit etmemi sağlar.
npe hatalarının kolay tespit edilebildiğini ben şu ana kadar ne gördüm ne de duydum. Bu kısmı direkt es geçiyorum zaten aşağıda olması gerekeni gösterdim.

Java:
// class AddressList
public void addAddress(String userInput) {
    // seçenek 1: null kullanmak.
    Address address = Parsers.parseAddress(userInput);
    if (address == null) {
        System.out.println("Belirtilen adres geçersiz!");
        System.exit(-1);
    } else {
        this.internal.add(address);
    }

    // seçenek 2: null kullanmamak.
    this.internal.add(Parsers.parseAddress(userInput));
}

Yukarıdaki örnekte her iki seçeneğe de baktığımızda 2. seçeneğin çok daha temiz ve anlaşılır olduğu bariz bir biçimde ortada.

Öncelikle 1. seçenekte ne olduğunu anlatayım. Parsers.parseAddress() metotu kendisine gelen Stringi geçerli bir adres olarak görmediğinde null döndürmekte. Dolayısı ile bizde metotu kullandıktan sonra null kontrolü yapmak zorundayız. Aksi durumda listemize biz farkına varmadan bir null eklenmiş olur ve ileride eklenilen bu null yüzünden npe ile karşılaşırız (ne kadar ileride olduğu belli değil. Ya 1 milyon kullanıcıdan sadece 10 tanesine denk gelirse?).

2. seçenekte ise Parsers.parseAddress() metotu null döndürmek yerine direkt olarak bir exception throwlar ve programın çalışmasını sonlandırır. Buna
Linki görebilmek için üye olmanız gerekiyor. Giriş yap veya üye ol.
denir.

2. seçenek bize hatayı anında farkettirir ve hızlı ve kolayca çözmemize yardımcı olur. Öte yandan 1. seçeneği kullandığımızda bir null kontrolü yapmamız gerekir ve eğer ki olur da bu null kontrolünü unutursak (büyük bir codebase ve daha kompleks metotlarla çalışırsan böyle bir şeyi gözden kaçırabilmen oldukça mümkündür), yaptığımız testler sırasında ortada bir sorun olmadığını düşünerek programımızı productiona yollayabilir ve kullanıcıların uzun zamanlı kullanımları sonucunda npe ile karşılaşmalarına sebep olabiliriz. İşin kötü yanı ise bu npe nin neden ve nereden geldiğini bulmamız çok çok zor olacaktır. Çünkü daha önce de söylediğim gibi hatanın ne zaman ve ne şartlar altında geldiğini bilemeyiz.

Java:
//// uygulama 1
public User findUserByName(String name) {
    userId = this.database.users.fetch(name);
    return userId == 0 ? null : new User(userId);
}

// kullanım 1
User pib = findUserByName("personinblack");

if (pib != null) {
    pib.sendMessage("hello world");
}

// bir başka yerde
if (pib != null) {
    groupA.add(pib);
}

// bambaşka bir yerde ve yine null kontrolü
if (pib != null) {
    pib.terminateAccount();
}

// null kontrolü unutulursa
pib.sendMessage("hello world"); // "pib" objesi bize dolaylı yoldan ulaşmışsa nereden geldiği belli olmayan bir npe

//---------------------------------------------------------------------------------------------------//

//// uygulama 2
public class UnknownUser extends User {
    @Override
    public void sendMessage(String message) {
        // TODO: bununla alakalı bir debug mesajı gönderilebilir.
        return;
    }

    @Override
    public void terminateAccount() {
        // TODO: gerekirse üstteki metot ile aynı şekilde.
        return;
    }
}

public User findUserByName(String name) {
    userId = this.database.users.fetch(name);
    if (userId == 0) {
        return new UnknownUser();
    } else {
        return new User(userId);
    }
}

// kullanım 2
User pib = findUserByName('personinblack');

pib.sendMessage("hello world");

// bir başka yerde
groupA.add(pib);

// bambaşka bir yerde
pib.terminateAccount();

Bu örnekte 1. yönteme zaten aşina olduğunu varsayıyorum. Obje ile etkileşime geçilmeden önce her seferinde null kontrolü gerektiren bir yöntem. Olur da dalgınlığına falan denk gelir de kontrol etmeyi unutursan vay haline. Daha yararlı işlere harcayabileceğin değerli vaktini saçma sapan bir npe ile geçirmek isteyeceğini sanmıyorum.

Peki 2. yöntemde ne yapıyoruz? null döndürmek yerine bir "null objesi" döndürüyoruz. UnknownUser objesi, User objesi ile aynı özelliklere sahip fakat bazı metotları kullanılamaz durumda. Bu metotlar olur da kullanılırsa bir debug mesajı gönderebilir (hiçbir zaman böyle bir şeye ihtiyacın olmamalı) ve hiçbir şey yapmadan kaldığın yerden devam edebilirsin.

Tüm bunlara rağmen ısrarla her yeri null kontrolleri ile dolu ve her an hata verip patlayabilecek bir kod yazmayı tercih ediyorsan keyfin bilir.
 
Son düzenleme:

LifeMCServer

Nether Yerlisi
En iyi cevaplar
98
Bu mantıkla düşünürsek, bizim gözümüzden kaçan hiçbir null olmamalı ve buna bağlı olarak hiç npe görmemeliyiz. Eğer ki sen ve beraber çalıştığın insanlar bu kadar kusursuzsa söyleyebileceğim bir şey yok, zaten npe görmüyorsunuz ne mutlu size. Fakat null kullanıyor ve npe lerle karşılaşıyorsan iş değişir. Zira null olamayacağını düşündüğün fakat null olan bir değişken olmazsa npe de olmaz.

Öte yandan null yerine varsayılan bir değer veya bir "null objesi" döndürdüğünde hatayı gizlemiş falan olmazsın. Bir metot, içerisinde istenen elementlerin bulunduğu dolu bir liste yerine boş bir liste döndürdüğünde, program dolu liste ile yapacağı şeyi boş liste ile de yapabilir. Eğer ki program beklendiği gibi çalışmıyorsa sıkıntının dönen bu liste olduğunu anlayabilmek, programın ölmesine sebep olan npe nin kaynağını bulabilmekten çok daha kolay ve çabuktur. "null objesi"ne aşağıda değineceğim.


Söylediğim söz yanlış değil çünkü dünya genelindeki büyük yazılım firmaları özellikle null kullanımını yasaklarlar. Çalışanlarının null kullanmasına izin vermeyerek müşterilerine teslim ettikleri programların npe sebebiyle crash yemesini engellerler. Sen hiç önemli bir Android uygulamasının npe ile çöktüğünü gördün mü? Ek olarak tanınan ve bilinen birçok önemli ismin de bu konuda makaleleri mevcuttur.


Optional dilin kendisinde olan bir şey zaten????


Eğer ki bağımlı olduğun bir kütüphanenin bir metotunun null döndürebilme olasılığı varsa maalesef null kontrolü yapmak zorundasın. Fakat bu senin değil, kütüphanenin problemidir ve bununla pek sık karşılaşılmaz.


Program en ufak bir yanlış çalışma halinde npe vererek sonlanırsa, programı kullanmaya çalışan kişi veya kişiler ne yapacaklar? Mesela Whatsapp'ın son sürümünde senin hiç kullanmadığın bir özellik sıkıntılı olsa ve sen sırf bunun yüzünden arkadaşlarınla haberleşemesen ne olur? Peki ya tüm uygulamanın npe yüzünden sonlandırılması yerine sadece hatalı olan o özellik kullanılamaz olsa?


npe hatalarının kolay tespit edilebildiğini ben şu ana kadar ne gördüm ne de duydum. Bu kısmı direkt es geçiyorum zaten aşağıda olması gerekeni gösterdim.

Java:
// class AddressList
public void addAddress(String userInput) {
    // seçenek 1: null kullanmak.
    Address address = Parsers.parseAddress(userInput);
    if (address == null) {
        System.out.println("Belirtilen adres geçersiz!");
        System.exit(-1);
    } else {
        this.internal.add(address);
    }

    // seçenek 2: null kullanmamak.
    this.internal.add(Parsers.parseAddress(userInput));
}

Yukarıdaki örnekte her iki seçeneğe de baktığımızda 2. seçeneğin çok daha temiz ve anlaşılır olduğu bariz bir biçimde ortada.

Öncelikle 1. seçenekte ne olduğunu anlatayım. Parsers.parseAddress() metotu kendisine gelen Stringi geçerli bir adres olarak görmediğinde null döndürmekte. Dolayısı ile bizde metotu kullandıktan sonra null kontrolü yapmak zorundayız. Aksi durumda listemize biz farkına varmadan bir null eklenmiş olur ve ileride eklenilen bu null yüzünden npe ile karşılaşırız (ne kadar ileride olduğu belli değil. Ya 1 milyon kullanıcıdan sadece 10 tanesine denk gelirse?).

2. seçenekte ise Parsers.parseAddress() metotu null döndürmek yerine direkt olarak bir exception throwlar ve programın çalışmasını sonlandırır. Buna
Linki görebilmek için üye olmanız gerekiyor. Giriş yap veya üye ol.
denir.

2. seçenek bize hatayı anında farkettirir ve hızlı ve kolayca çözmemize yardımcı olur. Öte yandan 1. seçeneği kullandığımızda bir null kontrolü yapmamız gerekir ve eğer ki olur da bu null kontrolünü unutursak (büyük bir codebase ve daha kompleks metotlarla çalışırsan böyle bir şeyi gözden kaçırabilmen oldukça mümkündür), yaptığımız testler sırasında ortada bir sorun olmadığını düşünerek programımızı productiona yollayabilir ve kullanıcıların uzun zamanlı kullanımları sonucunda npe ile karşılaşmalarına sebep olabiliriz. İşin kötü yanı ise bu npe nin neden ve nereden geldiğini bulmamız çok çok zor olacaktır. Çünkü daha önce de söylediğim gibi hatanın ne zaman ve ne şartlar altında geldiğini bilemeyiz.

Java:
//// uygulama 1
public User findUserByName(String name) {
    userId = this.database.users.fetch(name);
    return userId == 0 ? null : new User(userId);
}

// kullanım 1
User pib = findUserByName("personinblack");

if (pib != null) {
    pib.sendMessage("hello world");
}

// bir başka yerde
if (pib != null) {
    groupA.add(pib);
}

// bambaşka bir yerde ve yine null kontrolü
if (pib != null) {
    pib.terminateAccount();
}

// null kontrolü unutulursa
pib.sendMessage("hello world"); // "pib" objesi bize dolaylı yoldan ulaşmışsa nereden geldiği belli olmayan bir npe

//---------------------------------------------------------------------------------------------------//

//// uygulama 2
public class UnknownUser extends User {
    @Override
    public void sendMessage(String message) {
        // TODO: bununla alakalı bir debug mesajı gönderilebilir.
        return;
    }

    @Override
    public void terminateAccount() {
        // TODO: gerekirse üstteki metot ile aynı şekilde.
        return;
    }
}

public User findUserByName(String name) {
    userId = this.database.users.fetch(name);
    if (userId == 0) {
        return new UnknownUser();
    } else {
        return new User(userId);
    }
}

// kullanım 2
User pib = findUserByName('personinblack');

pib.sendMessage("hello world");

// bir başka yerde
groupA.add(pib);

// bambaşka bir yerde
pib.terminateAccount();

Bu örnekte 1. yönteme zaten aşina olduğunu varsayıyorum. Obje ile etkileşime geçilmeden önce her seferinde null kontrolü gerektiren bir yöntem. Olur da dalgınlığına falan denk gelir de kontrol etmeyi unutursan vay haline. Daha yararlı işlere harcayabileceğin değerli vaktini saçma sapan bir npe ile geçirmek isteyeceğini sanmıyorum.

Peki 2. yöntemde ne yapıyoruz? null döndürmek yerine bir "null objesi" döndürüyoruz. UnknownUser objesi, User objesi ile aynı özelliklere sahip fakat bazı metotları kullanılamaz durumda. Bu metotlar olur da kullanılırsa bir debug mesajı gönderebilir (hiçbir zaman böyle bir şeye ihtiyacın olmamalı) ve hiçbir şey yapmadan kaldığın yerden devam edebilirsin.

Tüm bunlara rağmen ısrarla her yeri null kontrolleri ile dolu ve her an hata verip patlayabilecek bir kod yazmayı tercih ediyorsan keyfin bilir.


Bir uygulama (veya program her ne der isen) bir NPE yüzünden çöküyor ise bu yine geliştiricilerin suçudur. Hata yakalama raporlama üzerine daha fazla önlem almaları gerekir. Bir program bir NPE yüzünden beklenmedik şekilde çökmemeli. Uncaught exception handler ayarlanıp hata otomatik veya kullanıcıya sorularak raporlanmalı. Hatalar zaten kullanıcılar için değil geliştiriciler içindir.

Optional'ın dil desteği yok derken diğer bazı dillerde type isminin sonuna ? vesaire konularak bir şeyin "null olabileceğinin" belirtilmesini kastetmiştim.

Null yerine UnknownUser döndürmek kullanıcıyı var gibi göstermektir. Bu durumda if (user instanceof UnknownUser) yapmamız, if (user == null) yapmamız gibidir. Sadece birinde null ve NPE yoktur. NPE olmasının benim için kötü değil aksine iyi bir şey olmasını belirtmiştim zaten. Aynı şeyleri tekrar tekrar yazmayacağım. Okumak isteyen yukarıya çıkıp okuyabilir.

"Null olamayacağını düşündüğü bir değişken null oluyor ise bu onun hatasıdır."
"Bu mantıkla düşünürsek, bizim gözümüzden kaçan hiçbir null olmamalı ve buna bağlı olarak hiç npe görmemeliyiz."

Burada hata yaptığı yer değişkenin null olması değil, onun null olamayacağını düşünmesi. Basit bir null kontrolü veya uncaught exception handler ekleyip hatayı takip etmek bu kadar zor olmasa gerek? Yani neden null olamayacağını düşünüyor?

Java:
//// uygulama 1
public User findUserByName(String name) {
    userId = this.database.users.fetch(name);
    return userId == 0 ? null : new User(userId);
}

// kullanım 1
User pib = findUserByName("personinblack");

if (pib != null) {
    pib.sendMessage("hello world");
}

// bir başka yerde
if (pib != null) {
    groupA.add(pib);
}

// bambaşka bir yerde ve yine null kontrolü
if (pib != null) {
    pib.terminateAccount();
}

// null kontrolü unutulursa
pib.sendMessage("hello world"); // "pib" objesi bize dolaylı yoldan ulaşmışsa nereden geldiği belli olmayan bir npe


Bu örnekte zaten pib bir local variable olarak kaydedilip null kontrolü yapılmış. Tekrar tekrar null kontrolü yapmaya gerek yok. Farklı yerlerde kullanıyor isek zaten null kontrolü yapmalıyız. Null kullanabilecek iken neden boş yere bir null objesi oluşturup GC'ye çöp biriktirelim?
 

LifeMCServer

Nether Yerlisi
En iyi cevaplar
98
aman çok şey biliyorum, o terim benim şu terim senin
bilgilendirme için teşekkürler.


Boş mesaj atmayı bırak. Mesajların hiçbir anlam ifade etmiyor. İsmini javabey yapıp profil resmine kahve koyunca maalesef ultra mükemmel javacı olmuyorsun. Mesajlarının çoğu boş. Biraz inceledim de eklenti paylaşım konularına galiba "decompile edeyim de kod stilini eleştireyim" diye giriyorsun?
 

javabey

git add Brain.java in/earth/people/brainless
En iyi cevaplar
0
Boş mesaj atmayı bırak. Mesajların hiçbir anlam ifade etmiyor. İsmini javabey yapıp profil resmine kahve koyunca maalesef ultra mükemmel javacı olmuyorsun. Mesajlarının çoğu boş. Biraz inceledim de eklenti paylaşım konularına galiba "decompile edeyim de kod stilini eleştireyim" diye giriyorsun?
bu öfke ne acaba? boş mesaj atmıyorum gayet yerinde şeyler söylüyorum teşekkür ettim ve bi null u bu kadar abartıp sürekli terimsel ifadelerle insanları cahilmişsiniz gibi göstermenize biraz laf ettim, gerekli cevabı arkadaşlar verince de hemen sinirlendiniz anlaşılan, kod stilini eleştirmekte ne sakınca var ayrıca yanlış bir şey mi arkadaşların kendini geliştirmesine müsade etmiyceksen sen nasıl yazılım ile alakalı bilgiler verebiliyorsun?

kendimi ultra mükemmel mega combo javacı olarak görüyorumu kim söylüyor, pp mi ve nicki mi istediğim gibi yaparım, fazla ön yargılı davranıyorsun, belkide ben c# ile uğraşan ve javadan nefret eden ama insanları kendimi javacı gibi gösteren biriyim, nerden biliyorsunuz?
 

LifeMCServer

Nether Yerlisi
En iyi cevaplar
98
bu öfke ne acaba? boş mesaj atmıyorum gayet yerinde şeyler söylüyorum teşekkür ettim ve bi null u bu kadar abartıp sürekli terimsel ifadelerle insanları cahilmişsiniz gibi göstermenize biraz laf ettim, gerekli cevabı arkadaşlar verince de hemen sinirlendiniz anlaşılan, kod stilini eleştirmekte ne sakınca var ayrıca yanlış bir şey mi arkadaşların kendini geliştirmesine müsade etmiyceksen sen nasıl yazılım ile alakalı bilgiler verebiliyorsun?

kendimi ultra mükemmel mega combo javacı olarak görüyorumu kim söylüyor, pp mi ve nicki mi istediğim gibi yaparım, fazla ön yargılı davranıyorsun, belkide ben c# ile uğraşan ve javadan nefret eden ama insanları kendimi javacı gibi gösteren biriyim, nerden biliyorsunuz?

Ben kimseye cahil demiyorum konuda da kullandığım terimleri her zaman açıklarım türkçesini yazarım kaldı ki bazılarının türkçeleri gerçekten anlamsız oluyor. Konuyu geçiyorum mesajlardan bahsediyor isen tartışma tek taraflı olmuyor.. Tabii bunu sadece bana ithafen söyledi isen.

"Gerekli cevabı arkadaşlar verince de hemen sinirlendiniz anlaşılan"

Bu cümleni biraz açar mısın? Sen tartışmaya dahil değilsin, konu hakkında yorum yapmıyorsun, kimsenin mesajını alıntılamadan çıkıp alakasız bir şekilde mesaj atmak için "o terim benim şu terim senin" tarzı anlamsız bir şey diyorsun. Objektif olabilseydin zaten şu cümleyi kullanmazdın.

Ayrıca arkadaşlar neye hangi cevabı verdi? Ben sana ithafen bir şey dedim de ona sen değil bir başkası mı cevap verdi ne diyorsun? Kaldı ki birinin benim yazdığım şeye cevap vermesi benim de ona cevap vermem, böyle gitmesi çok doğal bir şey?

Benim bahsettiğim nokta şu ki sen insanların kendini geliştirmesini sağlamıyorsun aksine heveslerini kırıyorsun ve şunu da bil ki decompile edilmiş kod orijinal koddan çok farklıdır. Kaldı ki incelediğim kısımlarda sen öneriden çok "çöp", "çok kötü" tarzı ihtamlarda bulunuyorsun ve önemsiz şeyleri vurguluyorsun.
 

javabey

git add Brain.java in/earth/people/brainless
En iyi cevaplar
0
Ben kimseye cahil demiyorum konuda da kullandığım terimleri her zaman açıklarım türkçesini yazarım kaldı ki bazılarının türkçeleri gerçekten anlamsız oluyor. Konuyu geçiyorum mesajlardan bahsediyor isen tartışma tek taraflı olmuyor.. Tabii bunu sadece bana ithafen söyledi isen.

"Gerekli cevabı arkadaşlar verince de hemen sinirlendiniz anlaşılan"

Bu cümleni biraz açar mısın? Sen tartışmaya dahil değilsin, konu hakkında yorum yapmıyorsun, kimsenin mesajını alıntılamadan çıkıp alakasız bir şekilde mesaj atmak için "o terim benim şu terim senin" tarzı anlamsız bir şey diyorsun. Objektif olabilseydin zaten şu cümleyi kullanmazdın.

Ayrıca arkadaşlar neye hangi cevabı verdi? Ben sana ithafen bir şey dedim de ona sen değil bir başkası mı cevap verdi ne diyorsun? Kaldı ki birinin benim yazdığım şeye cevap vermesi benim de ona cevap vermem, böyle gitmesi çok doğal bir şey?

Benim bahsettiğim nokta şu ki sen insanların kendini geliştirmesini sağlamıyorsun aksine heveslerini kırıyorsun ve şunu da bil ki decompile edilmiş kod orijinal koddan çok farklıdır. Kaldı ki incelediğim kısımlarda sen öneriden çok "çöp", "çok kötü" tarzı ihtamlarda bulunuyorsun ve önemsiz şeyleri vurguluyorsun.
biraz fazla kin besleyen insanlardansın sanırım ya da öfke kontorül biraz zayıf, konuya dahil olup olmamam önemli değil, kendi aranızda tartışırken gayet normal konuşuyorsun, ama biri sana laf söyleyince hemen celalleniyorsun anlaşılan.
 

LifeMCServer

Nether Yerlisi
En iyi cevaplar
98
biraz fazla kin besleyen insanlardansın sanırım ya da öfke kontorül biraz zayıf, konuya dahil olup olmamam önemli değil, kendi aranızda tartışırken gayet normal konuşuyorsun, ama biri sana laf söyleyince hemen celalleniyorsun anlaşılan.

Sen nerede bana laf söyledin? Ben hiçbir şey için alınmadım veya celallenmedim sadece konuya 2 dir boş boş yorum atıyorsun onu belirttim tepkimi gösterdim (kaldı ki sadece bu 2 mesajını değil birçok mesajını inceledim. yukarıda belirttim nasıl "kendilerini geliştirsinler diye yorum atıyorum" diyip "çöp, çok kötü" gibi ihtamlarda bulunduğunu). Mesajlarının boş ve anlamsız olduğunu sende biliyorsun, hatta silmişsin veya silinmiş, bilemiyorum. Artık daha fazla uzatma ve uzatmayın. Bir rehber konusunu tartışma konusuna çevirdiğiniz yetmedi mi sizce de?
 

Whoisthatinblack

Taş Madencisi
En iyi cevaplar
0
Bir uygulama (veya program her ne der isen) bir NPE yüzünden çöküyor ise bu yine geliştiricilerin suçudur. Hata yakalama raporlama üzerine daha fazla önlem almaları gerekir. Bir program bir NPE yüzünden beklenmedik şekilde çökmemeli. Uncaught exception handler ayarlanıp hata otomatik veya kullanıcıya sorularak raporlanmalı. Hatalar zaten kullanıcılar için değil geliştiriciler içindir.

Optional'ın dil desteği yok derken diğer bazı dillerde type isminin sonuna ? vesaire konularak bir şeyin "null olabileceğinin" belirtilmesini kastetmiştim.

Null yerine UnknownUser döndürmek kullanıcıyı var gibi göstermektir. Bu durumda if (user instanceof UnknownUser) yapmamız, if (user == null) yapmamız gibidir. Sadece birinde null ve NPE yoktur. NPE olmasının benim için kötü değil aksine iyi bir şey olmasını belirtmiştim zaten. Aynı şeyleri tekrar tekrar yazmayacağım. Okumak isteyen yukarıya çıkıp okuyabilir.

"Null olamayacağını düşündüğü bir değişken null oluyor ise bu onun hatasıdır."
"Bu mantıkla düşünürsek, bizim gözümüzden kaçan hiçbir null olmamalı ve buna bağlı olarak hiç npe görmemeliyiz."

Burada hata yaptığı yer değişkenin null olması değil, onun null olamayacağını düşünmesi. Basit bir null kontrolü veya uncaught exception handler ekleyip hatayı takip etmek bu kadar zor olmasa gerek? Yani neden null olamayacağını düşünüyor?

Java:
//// uygulama 1
public User findUserByName(String name) {
    userId = this.database.users.fetch(name);
    return userId == 0 ? null : new User(userId);
}

// kullanım 1
User pib = findUserByName("personinblack");

if (pib != null) {
    pib.sendMessage("hello world");
}

// bir başka yerde
if (pib != null) {
    groupA.add(pib);
}

// bambaşka bir yerde ve yine null kontrolü
if (pib != null) {
    pib.terminateAccount();
}

// null kontrolü unutulursa
pib.sendMessage("hello world"); // "pib" objesi bize dolaylı yoldan ulaşmışsa nereden geldiği belli olmayan bir npe


Bu örnekte zaten pib bir local variable olarak kaydedilip null kontrolü yapılmış. Tekrar tekrar null kontrolü yapmaya gerek yok. Farklı yerlerde kullanıyor isek zaten null kontrolü yapmalıyız. Null kullanabilecek iken neden boş yere bir null objesi oluşturup GC'ye çöp biriktirelim?

Bir uygulama (veya program her ne der isen) bir NPE yüzünden çöküyor ise bu yine geliştiricilerin suçudur. Hata yakalama raporlama üzerine daha fazla önlem almaları gerekir. Bir program bir NPE yüzünden beklenmedik şekilde çökmemeli. Uncaught exception handler ayarlanıp hata otomatik veya kullanıcıya sorularak raporlanmalı.
Ortada bir npe varsa programın çökmesi gerekmez mi? Kendin söylemedin mi hataları susturmak kötü bir şey diye? Hangi söylediğinin doğru olduğunu kabul etmeliyiz? Biz hataları susturmuyorsak ve programımız npe yüzünden çökmüyorsa oluşturduğun bu konunun ne önemi var, niye açtın bu konuyu? Kimsenin zaten npe ile uğraşmaması lazım öyle değil mi? Ha ama sen hataları susturup programın kullanıcıya veya onun deneyimine zarar verebilecek olmasına rağmen çalışmaya devam etmesi gerektiğini düşünüyorsan burada sana söyleyebileceğim hiçbir şey yok; zaten kendinle çelişiyorsun.

Optional'ın dil desteği yok derken diğer bazı dillerde type isminin sonuna ? vesaire konularak bir şeyin "null olabileceğinin" belirtilmesini kastetmiştim.
Ha sonuna soru işareti koymuşsun ha Optional kullanmışsın ne farkeder? Amaç aynı, sonuç aynı...

Null yerine UnknownUser döndürmek kullanıcıyı var gibi göstermektir. Bu durumda if (user instanceof UnknownUser) yapmamız, if (user == null) yapmamız gibidir. Sadece birinde null ve NPE yoktur. NPE olmasının benim için kötü değil aksine iyi bir şey olmasını belirtmiştim zaten. Aynı şeyleri tekrar tekrar yazmayacağım. Okumak isteyen yukarıya çıkıp okuyabilir.
Kullancıyı var gibi göstermiyoruz hayır. Eğer ki sen kullanıcının var olup olmadığını kontrol eden bir kod yazmışsan ve bu kod içerisinde kullanıcı varmış gibi davranıp UnknownUser döndürmüşsen bu senin sorunundur. Böyle bir durumda yapman gereken şey ilk örnekteki gibi exception throwlayarak programın sonlanmasını sağlamaktır. Buradaki örnekte kullanıcının varlığını kontrol etmiyoruz; sadece veritabanında kullanıcıyı arayıp bulmaya çalışıyoruz. Kullanıcı bulunamadığında sana sunulan "UnknownUser" objesindeki metotların bazılarını exception throwlayacak şekilde düzenleyebilirsin. Ve kullanıcının varlığını gerektiğinde if (user.exists()) { benzeri bir biçimde test edebilirsin (bunu sadece bir kere yapman gerekmeli, tüm codebase i bununla doldurmamalısın).

Burada hata yaptığı yer değişkenin null olması değil, onun null olamayacağını düşünmesi. Basit bir null kontrolü veya uncaught exception handler ekleyip hatayı takip etmek bu kadar zor olmasa gerek? Yani neden null olamayacağını düşünüyor?
null olamayacağını düşünmek zorunda değil. 40 farklı kişinin elinin değdiği, 50k - 100k ve belki daha fazla satır bir codebasede bir metotun döndürdüğü şeyin null olduğu gözden kaçabiliyor. Bu 50k bile olsa gelen npe nin nereden geldiğini bulmak tam anlamıyla işkence haline dönüşür. Sen en fazla ne kadar büyük bir proje ile çalıştın bilmiyorum fakat bu bahsettiğim şey bütün programcıların kabusudur.

Bu örnekte zaten pib bir local variable olarak kaydedilip null kontrolü yapılmış. Tekrar tekrar null kontrolü yapmaya gerek yok. Farklı yerlerde kullanıyor isek zaten null kontrolü yapmalıyız.
Dikkatini çekerim kod içerisine comment line ekleyip "başka bir yerde" demişim aynı yer olabilir mi? Buradaki olay bütün kaynak kodunun if (x == null) { lerle dolup okunamaz bir hale gelmesi ve her yerde, sürekli null kontrolü yapmak zorunda olmamızdır.

Null kullanabilecek iken neden boş yere bir null objesi oluşturup GC'ye çöp biriktirelim?
Performans konusunda düşünmen gereken en son şey oluşturacağın basit bir obje olacaktır. Önemli olan o objenin ne yaptığı ve senin o obje ile ne yaptığındır. Yoksa bir kaç yüz tane null objesi oluşturdun diye ram kullanımın artacak değil. GC bununla ilgilenemeyecek kadar zavallı mı? Hayır.

Edit: Donald Knuth'ın bir sözü:
We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
 
Son düzenleme:
Üst