Java - Nedir bu NullPointerException?

LifeMCServer

Nether Yerlisi
Mesajlar
2,410
En iyi cevaplar
98
Beğeniler
2,461
Puanları
10,250
Ruh hali
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.


Ha sonuna soru işareti koymuşsun ha Optional kullanmışsın ne farkeder? Amaç aynı, sonuç aynı...


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).


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.


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.


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.


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.


Benim dediğim durumda hatayı susturmuyorsun sadece programı çökertmiyorsun ve hatayı raporluyorsun, otomatik veya kullanıcıya sorarak. Orada da yazmıştım aynısını neresini anlamadığını anlamadım? Sen demiyor musun programın çökmesi kötü bir şey diye?

Kullanıcı bulunamadığında sana sunulan "UnknownUser" objesindeki metotların bazılarını exception throwlayacak şekilde düzenleyebilirsin.


Olması gerekende bu zaten. Olmayan bir kullanıcı üzerinde işlem yapılmaya neden çalışılsın? İşlem yapılmayacaksa neden boş obje oluşturulsun sadece hata verdirmek için? Exists kodunu yazabiliyoruz da neden null check koyamıyoruz?

Dediğin yöntem bana kalır ise şu durumda mantıklı sadece: "Eğer kullanıcının olup olmaması umurunda değil ise ve sadece kontrol yapmak istiyor isen." Mesela exists methodu bir boolean methodu, kullanıcının olup olmaması farketmiyor olmaması durumunda NPE yerine basitçe false döndürmek daha mantıklı olabilir dediğin gibi.

Dikkatini çekerim kod içerisine comment line ekleyip "başka bir yerde" demişim aynı yer olabilir mi?


Dikkatini çekerim bende orada "farklı yerlerde kullanıyor isek zaten null kontrolü eklemeliyiz" demişim. User#exists methodunu da aynı şekilde başka bir yerde kullanmaya kalkacaksak ve kullanıcının olup olmaması yapacağımız işlemi etkiliyor ise yine User#exists methodunu tekrar kullanmalıyız.

Yani burada null kullanmayarak performanstan readibility den bug free den production ready den her türlü gözle görülür avantajın çıkarın kazancın olması lazım ki bir şeyi kullanmaktan tamamen vazgeçesin. Bana kalırsa bu daha çok tercih meselesi. Sen zaten null kullanmıyorsundur öyle alışmışsındır kullanmazsın, o sana kalmış. Fakat ben null kullanıyorum null checkleri veya conditional expression (C#'da olan ve Java'da görmek istediğim özellik, x?.method/field şeklinde erişebiliyorsun) kullanmayı seviyorum ona alışmışım o da benim bileceğim iş. Kimin ne kullandığı açıkcası benim pekte umurumda değil.

Burada tartıştığımız şey her ne kadar hangisinin daha mantıklı iyi olduğu gibi görünse de benim burada savunduğum şey başından beri zaten "null iyidir, kullanın kullandırtın" değil de "isteyen kullanır, istemeyen kullanmaz" düşüncesi.

Burada konunun başından bari demek istediğim şeye gelir isek "ben null kullanmıyorum sizde kullanmayın, kullandırtmayın" olayı yanlış. Konuda "null şöyle güzeldir böyle güzeldir, her yerde kullanın kullandırtın" da denmediğine göre böyle bir tartışmanın çıkması bile baştan sona saçmalık.

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.


Burada performanstan bahsetmiyorum sadece mantık yolu ile ilerliyorum. Aynı işi sabit bir değer olan ve zaten hiçliği temsil eden null ile de yapabilecekken neden olmayan bir üyeyi temsil eden bir class açıp onun bir instancesini oluşturayım? Bir kaç null kontrolünden zaman kazanmak için mi? Ya da programın çökmesini engellemek için mi? Bu nereden çıktı bilmiyorum ama başta da dediğim gibi; hatalar veya çökmeler doğru yoldan tespit edilip raporlanmalı.
 

Whoisthatinblack

Taş Madencisi
Mesajlar
70
En iyi cevaplar
0
Beğeniler
85
Puanları
280
Benim dediğim durumda hatayı susturmuyorsun sadece programı çökertmiyorsun ve hatayı raporluyorsun, otomatik veya kullanıcıya sorarak. Orada da yazmıştım aynısını neresini anlamadığını anlamadım? Sen demiyor musun programın çökmesi kötü bir şey diye?




Olması gerekende bu zaten. Olmayan bir kullanıcı üzerinde işlem yapılmaya neden çalışılsın? İşlem yapılmayacaksa neden boş obje oluşturulsun sadece hata verdirmek için? Exists kodunu yazabiliyoruz da neden null check koyamıyoruz?

Dediğin yöntem bana kalır ise şu durumda mantıklı sadece: "Eğer kullanıcının olup olmaması umurunda değil ise ve sadece kontrol yapmak istiyor isen." Mesela exists methodu bir boolean methodu, kullanıcının olup olmaması farketmiyor olmaması durumunda NPE yerine basitçe false döndürmek daha mantıklı olabilir dediğin gibi.




Dikkatini çekerim bende orada "farklı yerlerde kullanıyor isek zaten null kontrolü eklemeliyiz" demişim. User#exists methodunu da aynı şekilde başka bir yerde kullanmaya kalkacaksak ve kullanıcının olup olmaması yapacağımız işlemi etkiliyor ise yine User#exists methodunu tekrar kullanmalıyız.

Yani burada null kullanmayarak performanstan readibility den bug free den production ready den her türlü gözle görülür avantajın çıkarın kazancın olması lazım ki bir şeyi kullanmaktan tamamen vazgeçesin. Bana kalırsa bu daha çok tercih meselesi. Sen zaten null kullanmıyorsundur öyle alışmışsındır kullanmazsın, o sana kalmış. Fakat ben null kullanıyorum null checkleri veya conditional expression (C#'da olan ve Java'da görmek istediğim özellik, x?.method/field şeklinde erişebiliyorsun) kullanmayı seviyorum ona alışmışım o da benim bileceğim iş. Kimin ne kullandığı açıkcası benim pekte umurumda değil.

Burada tartıştığımız şey her ne kadar hangisinin daha mantıklı iyi olduğu gibi görünse de benim burada savunduğum şey başından beri zaten "null iyidir, kullanın kullandırtın" değil de "isteyen kullanır, istemeyen kullanmaz" düşüncesi.

Burada konunun başından bari demek istediğim şeye gelir isek "ben null kullanmıyorum sizde kullanmayın, kullandırtmayın" olayı yanlış. Konuda "null şöyle güzeldir böyle güzeldir, her yerde kullanın kullandırtın" da denmediğine göre böyle bir tartışmanın çıkması bile baştan sona saçmalık.




Burada performanstan bahsetmiyorum sadece mantık yolu ile ilerliyorum. Aynı işi sabit bir değer olan ve zaten hiçliği temsil eden null ile de yapabilecekken neden olmayan bir üyeyi temsil eden bir class açıp onun bir instancesini oluşturayım? Bir kaç null kontrolünden zaman kazanmak için mi? Ya da programın çökmesini engellemek için mi? Bu nereden çıktı bilmiyorum ama başta da dediğim gibi; hatalar veya çökmeler doğru yoldan tespit edilip raporlanmalı.

Tartışmaya devam etmek istemiyorum ve nullün zararlarını özet geçerek konuyu kapatıyorum. Bundan sonra ister kullanmaya devam edersin ister etmezsin senin bileceğin iş. İkisini de dene, tarafını seç:
  1. Hangi metotun hangi şartlar altında null döndüreceğini bilebilmek için düzenli olarak kod okuma veya kod kendi kendini ifade edemeyeceği için null dönebilecek yerlere comment ekleme gereksinimini ortaya çıkarması.
  2. Sürekli olarak null kontrolü yapma gereksinimi ile kodun şişirilmesi ve null kontrolü unutulduğunda npe ile karşılaşılmasına neden olması. Alternatif: direkt exception throwlamak (failing fast) veya null objeleri kullanmak.
  3. "failing fast" yerine yavaş yavaş ölen, ölürken etrafında karmaşa oluşturan ve direkt olarak sorunun ne olduğunu söyleyebileceği yerde bunu yapmayan kodlar yazmamıza sebep olması.
  4. Bizi objeye yönelik düşünme şeklinden uzaklaştırması. Biz bir metottan bir obje bekliyorken metotun bize karşılığı olmayan bir şey döndürmesi OOP ye uygun bir davranış değildir. Bunun yerine beklenen objenin yapabildiklerinin bir kısmını yapabilen, o objenin yerini tutabilen bir başka obje döndürdürmek veya bir hata olduğunu belirtmek amacıyla exception throwlayarak programı sonlandırmak çok daha mantıklıdır.
  5. Mutable ve hazır olmayan objeler oluşturmamıza sebep olması:
    Java:
    public final class BlogPost {  
        private final Database database;
        private final int id;
    
        // bu değişken hem kullanıma hazır değil (update metotunu kullanmadan buna erişmemiz imkansız
        // ki update metotundan sonra bile null olmayacağı kesin değil) hem de mutable.
        // bunun dışındaki tüm değişkenlerde final bulunduğuna dikkat çekerim.
        private String content = null;
    
        public BlogPost(final Database database, final int id) {
            this.database = database;
            this.id = id;
        }
    
        public void update() {
            if (this.id != null && this.content == null) {
                this.content = database.fetchPost(this.id);
            }
        }
    }
 

LifeMCServer

Nether Yerlisi
Mesajlar
2,410
En iyi cevaplar
98
Beğeniler
2,461
Puanları
10,250
Ruh hali
Tartışmaya devam etmek istemiyorum ve nullün zararlarını özet geçerek konuyu kapatıyorum. Bundan sonra ister kullanmaya devam edersin ister etmezsin senin bileceğin iş. İkisini de dene, tarafını seç:
  1. Hangi metotun hangi şartlar altında null döndüreceğini bilebilmek için düzenli olarak kod okuma veya kod kendi kendini ifade edemeyeceği için null dönebilecek yerlere comment ekleme gereksinimini ortaya çıkarması.
  2. Sürekli olarak null kontrolü yapma gereksinimi ile kodun şişirilmesi ve null kontrolü unutulduğunda npe ile karşılaşılmasına neden olması. Alternatif: direkt exception throwlamak (failing fast) veya null objeleri kullanmak.
  3. "failing fast" yerine yavaş yavaş ölen, ölürken etrafında karmaşa oluşturan ve direkt olarak sorunun ne olduğunu söyleyebileceği yerde bunu yapmayan kodlar yazmamıza sebep olması.
  4. Bizi objeye yönelik düşünme şeklinden uzaklaştırması. Biz bir metottan bir obje bekliyorken metotun bize karşılığı olmayan bir şey döndürmesi OOP ye uygun bir davranış değildir. Bunun yerine beklenen objenin yapabildiklerinin bir kısmını yapabilen, o objenin yerini tutabilen bir başka obje döndürdürmek veya bir hata olduğunu belirtmek amacıyla exception throwlayarak programı sonlandırmak çok daha mantıklıdır.
  5. Mutable ve hazır olmayan objeler oluşturmamıza sebep olması:
    Java:
    public final class BlogPost {
        private final Database database;
        private final int id;
    
        // bu değişken hem kullanıma hazır değil (update metotunu kullanmadan buna erişmemiz imkansız
        // ki update metotundan sonra bile null olmayacağı kesin değil) hem de mutable.
        // bunun dışındaki tüm değişkenlerde final bulunduğuna dikkat çekerim.
        private String content = null;
    
        public BlogPost(final Database database, final int id) {
            this.database = database;
            this.id = id;
        }
    
        public void update() {
            if (this.id != null && this.content == null) {
                this.content = database.fetchPost(this.id);
            }
        }
    }

Hangi metotun hangi şartlar altında null döndüreceğini bilebilmek için düzenli olarak kod okuma veya kod kendi kendini ifade edemeyeceği için null dönebilecek yerlere comment ekleme gereksinimini ortaya çıkarması.

Metota @Nullable koymak çok mu zor acaba :D Comment koymak tamamen saçmalık olur. Nullable koyman hem javadoc'da vesaire gösterecektir hemde eğer IDE'n için geçerli olan Eclipse (org.eclipse.jdt.annotations) ve IntelliJ (jetbrains.annotations) gibi IDE'lerin kütüphanelerini & pluginlerini kullanır isen ekstra null analizi elde edersin. Ek olarak FindBugs / SpotBugs, Lombok vb. başka araçlar ile işini kolaylaştırabilirsin. Bunlardan zaten daha önceki mesajlarımda da bahsettim.

Sürekli olarak null kontrolü yapma gereksinimi ile kodun şişirilmesi ve null kontrolü unutulduğunda npe ile karşılaşılmasına neden olması. Alternatif: direkt exception throwlamak (failing fast) veya null objeleri kullanmak.

"failing fast" yerine yavaş yavaş ölen, ölürken etrafında karmaşa oluşturan ve direkt olarak sorunun ne olduğunu söyleyebileceği yerde bunu yapmayan kodlar yazmamıza sebep olması.

Hangisi daha mantıklı der isen exception throwlamak daha mantıklı en azından null obje kullanmaktan, fakat yinede hatayı benim yerime JVM'nin otomatik throwlaması daha mantıklı olur. Tabii kendi throwladığımız hataya ekstra bilgi vesaire eklemiyor veya özellikle onu catchlemiyor isek.

Bizi objeye yönelik düşünme şeklinden uzaklaştırması. Biz bir metottan bir obje bekliyorken metotun bize karşılığı olmayan bir şey döndürmesi OOP ye uygun bir davranış değildir. Bunun yerine beklenen objenin yapabildiklerinin bir kısmını yapabilen, o objenin yerini tutabilen bir başka obje döndürdürmek veya bir hata olduğunu belirtmek amacıyla exception throwlayarak programı sonlandırmak çok daha mantıklıdır.

Programı sonlandırmaktan daha mantıklı olan bir diğer şey ise hatayı yakalayıp (try catch veya uncaught exception handler ile) otomatik olarak veya kullanıcıya sorarak raporlamak. Önceki mesajında uygulamanın çökmesinin kötü olacağını falan söylemiyor muydun sen?

Bizi objeye yönelik düşünme şeklinden uzaklaştırması. Biz bir metottan bir obje bekliyorken metotun bize karşılığı olmayan bir şey döndürmesi OOP ye uygun bir davranış değildir.

Bir metottan obje bekleyebilirsin (javada sadece primitive typelar null olamaz). Fakat zaten methodun null döndürmesi beklenmedik bir durum olduğunun ve bu durumun methodu çağıran kişiyi alakadar ettiğinin göstergesidir zaten. Eğer bu durum methodu çağıran kişinin kendi çözümünü üretmesini (null check, throw vb) gerektirmiyor ise de method içerisinden throw ile hata atılır, gerekirse checked exception olarakta throws kısmına eklenir, eğer catchlenmesini zorunlu kılmak istiyor isek tabii.

Mutable ve hazır olmayan objeler oluşturmamıza sebep olması.

Kodda her şeyin final olması kodu daha temiz ve düzenli yapacaktır tabii ki fakat bu her şeyi final yapacağımız anlamına gelmiyor. Burada update methoduna gerek olmadan direk constructurda bilgiyi alır isek null kullanmadan ekstra olarak final kullanarak yapabiliriz fakat bu objeyi oluşturan kişinin update tarzı bir methodu çağırmadan direk constructurda çağırılmasını sağlar, buda objeyi constructor ile oluşturan kişi için daha az kontrol demek.
 

Whoisthatinblack

Taş Madencisi
Mesajlar
70
En iyi cevaplar
0
Beğeniler
85
Puanları
280
Metota @Nullable koymak çok mu zor acaba :D Comment koymak tamamen saçmalık olur. Nullable koyman hem javadoc'da vesaire gösterecektir hemde eğer IDE'n için geçerli olan Eclipse (org.eclipse.jdt.annotations) ve IntelliJ (jetbrains.annotations) gibi IDE'lerin kütüphanelerini & pluginlerini kullanır isen ekstra null analizi elde edersin. Ek olarak FindBugs / SpotBugs, Lombok vb. başka araçlar ile işini kolaylaştırabilirsin. Bunlardan zaten daha önceki mesajlarımda da bahsettim.





Hangisi daha mantıklı der isen exception throwlamak daha mantıklı en azından null obje kullanmaktan, fakat yinede hatayı benim yerime JVM'nin otomatik throwlaması daha mantıklı olur. Tabii kendi throwladığımız hataya ekstra bilgi vesaire eklemiyor veya özellikle onu catchlemiyor isek.



Programı sonlandırmaktan daha mantıklı olan bir diğer şey ise hatayı yakalayıp (try catch veya uncaught exception handler ile) otomatik olarak veya kullanıcıya sorarak raporlamak. Önceki mesajında uygulamanın çökmesinin kötü olacağını falan söylemiyor muydun sen?



Bir metottan obje bekleyebilirsin (javada sadece primitive typelar null olamaz). Fakat zaten methodun null döndürmesi beklenmedik bir durum olduğunun ve bu durumun methodu çağıran kişiyi alakadar ettiğinin göstergesidir zaten. Eğer bu durum methodu çağıran kişinin kendi çözümünü üretmesini (null check, throw vb) gerektirmiyor ise de method içerisinden throw ile hata atılır, gerekirse checked exception olarakta throws kısmına eklenir, eğer catchlenmesini zorunlu kılmak istiyor isek tabii.



Kodda her şeyin final olması kodu daha temiz ve düzenli yapacaktır tabii ki fakat bu her şeyi final yapacağımız anlamına gelmiyor. Burada update methoduna gerek olmadan direk constructurda bilgiyi alır isek null kullanmadan ekstra olarak final kullanarak yapabiliriz fakat bu objeyi oluşturan kişinin update tarzı bir methodu çağırmadan direk constructurda çağırılmasını sağlar, buda objeyi constructor ile oluşturan kişi için daha az kontrol demek.
Devam etmek istersen mikrofonunu al Discord'a gel (personinblack#6059). Seni ancak sesli olarak eğitebilirim, başka türlü anlayacağın yok.
 

MegaCrafter

Obsidyen Madencisi
Mesajlar
1,419
En iyi cevaplar
0
Beğeniler
1,542
Puanları
3,070
Bütün tartışmanın ucunda tek söyleyeceğim şu ki: İnsanları da lütfen kendiniz gibi monoton kafalara sokmayın. Sizin kullanamadığınız şeyi diğer insanlar kullanabiliyorsa bunu kıskanmayın. Yazılım dediğimiz şey hiçbir sistemi yapmanın tek bir yolu olmayan bir şey. İnsanlara yeni yollar açacağınıza sadece basit yollarda kendinizi asılı bırakıyorsunuz. OpenGL veya DirectX ve hatta Windows'un kendi sistemleri bile null kullanıyor ve hiçbir sorun yok.

Foruma geldiğimden beri forumda yazılımı ilerletmek istemiştim. Ama insanların heveslerini kırarak, onlara karşı yapıcı olmak yerine "ben yazılım biliyorum" kimliğinin arkasına sığınıp herkesi baltalayanlar yüzünden 3 senedir bu hiç olmadı. Ben de artık savaşmak istemiyorum çünkü maalesef insanları "sesli olarak bile eğitemiyoruz". Lütfen bu konuyu da burada kapatın.
 

Schaffer79

Sudan Çıkmış
Mesajlar
8
En iyi cevaplar
0
Beğeniler
58
Puanları
480
@Whoisthatinblack, uzun bir biçimde gayet güzel açıklamış neden null yerine Optional gibi farklı yöntemlere ihtiyaç duyulduğunu yine de anlaşılmayan yerler varsa toparlayıp bu uzun tartışmayı özetlemek isterim. İki sebepten ötürü birinci tercihiniz Optional kullanmak olmalı:
  • Optional ile stream ve Lambda ifadeleri doğrudan kullanılabilir.
  • Her zaman bir Optional objesi döndüreceğiniz için pratik olmayan null kontrolleri oluşturmazsınız.
İlk madde ile ilgili İnternet'te oldukça fazla örnek ve kaynak bulabilirsiniz ki Optional'ı harika yapan asıl olay bundan ibarettir, sadece bu bile null kullanılmaması için yeterli bir sebeptir. Bunun yanında null bize bu konuda kodun okunabilirliğini daha kötü hale getirmek dışında bir şey sunmaz, kısa ve net.

Konuda da daha çok ikinci madde üzerinden konuşulmuş ve benim de katıldığım şey null kullanmanın her zaman riskli olduğudur; istediğiniz kadar kodunuza güvenin ve hatta sadece kodunuza değil, başkalarının kullanımına açık yaptığınız kütüphaneye de istediğiniz kadar güvenin, bütün methodlarınıza Nullable notu koyun fakat her şey beklediğiniz şekilde gitmeyebilir zira hepimiz hata yapma ve unutma potansiyeli olan canlılarız.

Mükemmel kod yazabilen bir robot dahi olsanız, eğer projenize başka insanlar dahil olacaksa onların da bu anlamsız kontrolleri dikkate alması gerekir. Bütün kodu doğru yazsanız bile eklediğiniz gereksiz satırlar hakkında ne yapacağız? Bu tarz bir yaklaşım kodunuzun okunabirliğini de belli ölçüde düşürecektir. Ayrıca bir kütüphane kullanırken saçma kontroller veya hatalarla kim uğraşmak ister ki?

Yazımı toparlamam gerekirse Optional kullanılmaması için bir sebep yokken null kullanılmaması için sebep (NPE riski ve birden fazla kontrol eklemek vakit kaybı) vardır. Bu kişisel bir tercih olmaktan ziyade nesnel biçimde artıları ve eksileri olan bir seçimdir ve gerçeği tartışmak anlamsızdır. Elbette ufak bir program yapıyorsanız, kodunuza yeterli hakimiyetiniz varsa, okunabilirlik ve zaman sizin için bir şey ifade etmiyorsa Optional ya da bir referans objesi kullanmak da aynı şekilde size bir şey ifade etmeyecektir.

PS Optional'ın performans açısından etkisi az ve büyütülmesi gereken bir problem değil. Serileştirme işlemini de mümkün kılmak hiç zor değil.
 
Son düzenleme:

Reol

Sudan Çıkmış
Mesajlar
9
En iyi cevaplar
0
Beğeniler
24
Puanları
60
Yazımı toparlamam gerekirse Optional kullanılmaması için bir sebep yokken null kullanılmaması için sebep (NPE riski ve birden fazla null kontrolu eklemek vakit kaybı) vardır. Bu kişisel bir tercih olmaktan ziyade nesnel biçimde artıları ve eksileri olan bir seçimdir ve gerçeği tartışmak anlamsızdır. Elbette ufak bir program yapıyorsanız, kodunuza yeterli hakimiyetiniz varsa, okunabilirlik ve zaman sizin için bir şey ifade etmiyorsa Optional kullanmak da aynı şekilde size bir şey ifade etmeyecektir.
Optional kullanılmaması için "büyük" bir sebep yokmuş gibi gözüküyor lakin bu sebep olduğu gerçeğini değiştirmiyor. Gecenin bir saatinde yazdığınız için bu dezavantajların aklınızdan çıktığını veya ufak gözüktüğü için önemsemediğinizi sanıyorum. Optional kullanmanın avantajlarından bahsedilmiş fakat işte bunlar da eksileri.

Dezavantajlar

Optional'ın birçok avantajı olduğu gibi birkaç adet de dezavantajı mevcut. Optional kullanmak: heap size'ı arttırır, debug işlemini zorlaştırır ve XML, JSON gibi veri objelerini serileştirmeyi daha zor hale getirir.

Performans

Optional aslında wrapper görevi gören bir sınıf, normalde değişkeni tek objeyle referans ederken Optional ile birlikte iki objeye sahip olursunuz. Bu ekstra obje yazılımın performansını düşürebilir ve döngü içlerinde fark edilecek kadar etki edebilir.

Serileştirme (Serialization)

Optional doğrudan serileştirilemez, bundan dolayı çoğu durumda ekstra işlemler yapmanız gerekir. Serialize Optional - blog@CodeFX

Kapanış

Null, belki de Tony Hoare'nun dediği gibi bir hata olabilir ancak bu Optional'ın kusursuz olduğu anlamına gelmiyor. Optional kullanmak demek, null kullanmamak demek değildir çünkü ikisinin amaçları ve kullanıldığı yerler farklıdır. Optional'ın asıl amacı fonksiyonların döndürdüğü değişkenlerin varlığını pratik şekilde kontrol etmek ve buna göre işlem yapmaktır. java.util.Optional fields

Bu yüzden ikisinden birini seçmeye hiç lüzum yok! Gerçekten yazılım ile sıklıkla uğraşıyorsanız İkisine de ayrı ihtiyacınız olacak:şapka:
 
Son düzenleme:

LifeMCServer

Nether Yerlisi
Mesajlar
2,410
En iyi cevaplar
98
Beğeniler
2,461
Puanları
10,250
Ruh hali
Devam etmek istersen mikrofonunu al Discord'a gel (personinblack#6059). Seni ancak sesli olarak eğitebilirim, başka türlü anlayacağın yok.

Sen kendini ne olarak görüyorsun da "eğitmek" tabirini kullanabiliyorsun? Biz burada başından beri tartışıyoruz kimse kimseyi eğitmeye çalışmıyor çünkü biz zaten bunları biliyoruz. Son gelen iki arkadaş da gayet güzel yerlere değinmiş. Burada kimsenin kimseye bir şey anlatmaya ve yahut vazgeçirmeye çalıştığı yok çünkü zaten isteyen istediğini kullanıyor burada bizim yapmaya çalıştığımız şey insanlara bir fikir sunmak (eğer konumda null kullanın kullandırtın demiş olsaydım tamam, fakat ilk atılan yoruma bakar isek null kullanmayın ve kullandırtmayın şeklinde başladı her şey ben ise normal bir yanıt yazdım.) ve üzgünüm ki burada sizin yaptığınız şey insanlara "null kullanmayın, null kötü, null kullandırtmayın" dan başka bir şey değil. Benim demeye çalıştığım şey ise "ikisi de size Java'da veya herhangi bir dilde sunulmuş, neden birini tamamen (gözünüzde) yok edesiniz?"

@Whoisthatinblack, uzun bir biçimde gayet güzel açıklamış neden null yerine Optional gibi farklı yöntemlere ihtiyaç duyulduğunu yine de anlaşılmayan yerler varsa toparlayıp bu uzun tartışmayı özetlemek isterim. İki sebepten ötürü birinci tercihiniz Optional kullanmak olmalı:
  • Optional ile stream ve Lambda ifadeleri doğrudan kullanılabilir.
  • Her zaman bir Optional objesi döndüreceğiniz için pratik olmayan null kontrolleri oluşturmazsınız.
İlk madde ile ilgili İnternet'te oldukça fazla örnek ve kaynak bulabilirsiniz ki Optional'ı harika yapan asıl olay bundan ibarettir, sadece bu bile null kullanılmaması için yeterli bir sebeptir. Bunun yanında null bize bu konuda kodun okunabilirliğini daha kötü hale getirmek dışında bir şey sunmaz, kısa ve net.

Konuda da daha çok ikinci madde üzerinden konuşulmuş ve benim de katıldığım şey null kullanmanın her zaman riskli olduğudur; istediğiniz kadar kodunuza güvenin ve hatta sadece kodunuza değil, başkalarının kullanımına açık yaptığınız kütüphaneye de istediğiniz kadar güvenin, bütün methodlarınıza Nullable notu koyun fakat her şey beklediğiniz şekilde gitmeyebilir zira hepimiz hata yapma ve unutma potansiyeli olan canlılarız.

Mükemmel kod yazabilen bir robot dahi olsanız, eğer projenize başka insanlar dahil olacaksa onların da bu anlamsız kontrolleri dikkate alması gerekir. Bütün kodu doğru yazsanız bile eklediğiniz gereksiz satırlar hakkında ne yapacağız? Bu tarz bir yaklaşım kodunuzun okunabirliğini de belli ölçüde düşürecektir. Ayrıca bir kütüphane kullanırken saçma kontroller veya hatalarla kim uğraşmak ister ki?

Yazımı toparlamam gerekirse Optional kullanılmaması için bir sebep yokken null kullanılmaması için sebep (NPE riski ve birden fazla kontrol eklemek vakit kaybı) vardır. Bu kişisel bir tercih olmaktan ziyade nesnel biçimde artıları ve eksileri olan bir seçimdir ve gerçeği tartışmak anlamsızdır. Elbette ufak bir program yapıyorsanız, kodunuza yeterli hakimiyetiniz varsa, okunabilirlik ve zaman sizin için bir şey ifade etmiyorsa Optional ya da bir referans objesi kullanmak da aynı şekilde size bir şey ifade etmeyecektir.

PS Optional'ın performans açısından etkisi az ve büyütülmesi gereken bir problem değil. Serileştirme işlemini de mümkün kılmak hiç zor değil.

"Optional'ı harika yapan asıl olay bundan ibarettir, sadece bu bile null kullanılmaması için yeterli bir sebeptir."

Peki bana null'u evil yapan asıl olayın neyden ibaret olduğunu ve onun bile neden null kullanılmaması için yeterli olduğunu açıklar mısın? Kısa ve net, kesin şekilde bu tanımları nasıl neye göre koyuyorsunuz anlamadım.

Her zaman bir Optional objesi döndüreceğiniz için pratik olmayan null kontrolleri oluşturmazsınız.

Optional üzerinde de kullanmadan önce kontrol yapman gerekiyor, aksi takdir de get methodu hata verdirecektir (o verdirmese zaten yine NPE verecek), NPE'ye benzer bana kalırsa? Senin dediğin gibi lambda ve streamlerde kullanılabilir, orElse sayesinde varsayılan değer ile birlikte vesiare kullanılabilir, fakat null'un yerini almaz ve "null kullanılmaması için" sadece bu yeterli bir sebep değildir.

Nullable notu koyun fakat her şey beklediğiniz şekilde gitmeyebilir zira hepimiz hata yapma ve unutma potansiyeli olan canlılarız.

Nullable notu koyduğunda ve IDE'n de gerekli eklenti yüklü ise (yukarıda belirtmiştim) sen unutsan bile sana uyarı veriyor zaten. Kaldı ki çoğu zaman sen @Nullable yazmasan bile IDE ve yüklediğin diğer araçlar sana gerekli uyarıları sağlıyor (@Nullable yok fakat null döndürdün vb şeklinde). Bunlara ek olarak yeteri kadar test classı açarak test yapmak bu işin gerçek çözümüdür. Kaçamak yöntemler belirli durumlarda iyi olabilir (hatta kendi kullanım alanları vardır) fakat bu null'un tamamen kötü ve gereksiz olduğu anlamına gelmez; null kullanmıyorsanız hiç NPE almazsınız diye bir şey de yoktur, dışardan (illa bir ek kütüphane olmasına gerek yok) aldığınız herhangi bir veri her zaman null olabilir, buna Java'nın standart methodlarından bazıları da dahil. Null olamayacak tek şey primitive typelar'dır ve bunlarında default değerleri vardır, 0 dır çoğunun ki. Mesela bir Integer'ı int'e dönüştürdüğün de eğer 0 alıyor isen bunun Integer'ın gerçek değeri olan 0 mı yoksa null olduğu için mi 0 olduğunu anlayamazsın. Geri Integer'a çevirir isen de 0 olacaktır.

Optional kullanılmaması için "büyük" bir sebep yokmuş gibi gözüküyor lakin bu sebep olduğu gerçeğini değiştirmiyor. Gecenin bir saatinde yazdığınız için bu dezavantajların aklınızdan çıktığını veya ufak gözüktüğü için önemsemediğinizi sanıyorum. Optional kullanmanın avantajlarından bahsedilmiş fakat işte bunlar da eksileri.

Dezavantajlar

Optional'ın birçok avantajı olduğu gibi birkaç adet de dezavantajı mevcut. Optional kullanmak: heap size'ı arttırır, debug işlemini zorlaştırır ve XML, JSON gibi veri objelerini serileştirmeyi daha zor hale getirir.

Performans

Optional aslında wrapper görevi gören bir sınıf, normalde değişkeni tek objeyle referans ederken Optional ile birlikte iki objeye sahip olursunuz. Bu ekstra obje yazılımın performansını düşürebilir ve döngü içlerinde fark edilecek kadar etki edebilir.

Serileştirme (Serialization)

Optional doğrudan serileştirilemez, bundan dolayı çoğu durumda ekstra işlemler yapmanız gerekir. Serialize Optional - blog@CodeFX

Kapanış

Null, belki de Tony Hoare'nun dediği gibi bir hata olabilir ancak bu Optional'ın kusursuz olduğu anlamına gelmiyor. Optional kullanmak demek, null kullanmamak demek değildir çünkü ikisinin amaçları ve kullanıldığı yerler farklıdır. Optional'ın asıl amacı fonksiyonların döndürdüğü değişkenlerin varlığını pratik şekilde kontrol etmek ve buna göre işlem yapmaktır. java.util.Optional fields

Bu yüzden ikisinden birini seçmeye hiç lüzum yok! Gerçekten yazılım ile sıklıkla uğraşıyorsanız İkisine de ayrı ihtiyacınız olacak:şapka:

Bu yüzden ikisinden birini seçmeye hiç lüzum yok! Gerçekten yazılım ile sıklıkla uğraşıyorsanız İkisine de ayrı ihtiyacınız olacak:şapka:

Benim tartıştığım nokta da zaten bir şeyi tamamen çöpe atmanın mantıksız olmasaydı. Java'da ve birçok dil de sana null ve NPE (veya örneğin C#'da ki NRE) sunuluyor, bunu istediğin gibi kullanmak sana kalan bir şey tamamen.

Böyle harika bir postu nasıl toksik yığına çevirdiniz, merak konusu..

İlk öncelikle yorumun için teşekkürler. İkinci olarak hiçbir zaman harika olduğumu veya konunun kusursuz olduğunu iddia etmedim fakat yine de insanlara "NPE alıyorsanız null kullanmayın ve KULLANDIRTMAYIN" demek yerine böyle bir konu açmam kat kat daha iyi oldu bence :
 

javabey

git add Brain.java in/earth/people/brainless
Mesajlar
176
En iyi cevaplar
0
Beğeniler
180
Puanları
330
Ruh hali
Böyle harika bir postu nasıl toksik yığına çevirdiniz, merak konusu..
toksik mi :D toksiklikle ne alakası var? arkadaş nullu anlatmış diğerleride kullanılmaması için sebepler söylemiş ve alternatif sunmuş toksiklik göremiyorum
 

LifeMCServer

Nether Yerlisi
Mesajlar
2,410
En iyi cevaplar
98
Beğeniler
2,461
Puanları
10,250
Ruh hali
toksik mi :D toksiklikle ne alakası var? arkadaş nullu anlatmış diğerleride kullanılmaması için sebepler söylemiş ve alternatif sunmuş toksiklik göremiyorum

Konuyu tartışmalarla doldurdunuz lafını bile tek taraflı nasıl alabiliyorsun? Bu arada konuda nerede null'u nasıl anlatmışım? NPE'yi anlattım ve NPE null'a dayandığı için ufaktan null'u da anlattım fakat çıkıpta null kullanın kullandırtın demedim. Konuyu daha fazla kirletmeye gerek olmadığını bende zaten kaç mesaj öncesinden söylemiştim..
 

Elfen

Kızıltaş Madencisi
Mesajlar
508
En iyi cevaplar
0
Beğeniler
596
Puanları
1,230
Ben "null kullanmayın kullandırtmayın" derken kimseye gidip milletin kafasını eze eze "kullanmayacaksınlan!" tarzında bir şey demedim. Ortada bir konu var ve ben doğru bulduğum inandığım şeyi kanıtlarıyla ve bu alanda ileri gelenlerinde doğru bulduğunu belirttim. Megacrafter adındaki arkadaş ile gayet doğru düzgün bir tartışma içerisindeyken cevap veremediğinden olsa gerek işi saçma bir yöne çekti neymiş "Yıllardır yazılımcıların değişik değişik şeylere düşmanlık etmesini hala anlayamıyorum.". Ben ve benim gibiler konuyu falan baltalıyormuş? Şu hastalıklı zihniyetten çıkın artık sizin doğru bulduğunuz şeylerin doğru olmadığını söyleyen insanlara saldırmak yerine "hayır kardeşim senin dediğin yanlış çünkü bla bla bla" diyerek cevap verirsen zaten karşındaki de senin söylediklerinin aksini iddia edebiliyorsa düzgün bir şekilde açıklar. Son olarak söylüyorum kimseye saldırmadım açıklayarak durumu sundum ve buna rağmen konuyu kirlettiğim falan söyleniyor. Konuyu kirletmek?? Muhtemelen herkesin size öpücük vermesini falan bekliyorsunuz. Daha cevap vermeyeceğim örümcek ağlarınızla mutlu günler dilerim.

Edit: Ben kendimi asla ileri gelen olarak tanımlamadım ancak arkadaşta algıda seçicilik olduğundan dolayı böyle lanse ediyor.
 
Son düzenleme:

Schaffer79

Sudan Çıkmış
Mesajlar
8
En iyi cevaplar
0
Beğeniler
58
Puanları
480
Kendimi tam olarak ifade edememişim galiba, sorularınıza kısa ve spesifik yanıtlar vereceğim o halde. Konunun daha fazla kirlenmemesi ve amacından çıkmaması adına başka bir sorunuz olursa bana özel mesaj yoluyla ulaşmaktan çekinmeyin.
Peki bana null'u evil yapan asıl olayın neyden ibaret olduğunu ve onun bile neden null kullanılmaması için yeterli olduğunu açıklar mısın? Kısa ve net, kesin şekilde bu tanımları nasıl neye göre koyuyorsunuz anlamadım.
Null; değer olmayan bir değerdir. Bu cümle dahi Java gibi OOP bir dilde böyle bir tanımı kullanışsız yapar. İsterseniz örneklendirelim:
  1. Java'da Null, obje tipinin üzerine yazar bu da NPE gibi hatalara yol açar. Son kullanıcıya dağıtılmış bir yazılımda böyle bir hatanın kesinlikle alınmaması gerekir, aksine hatalar kontrol edilmeli ve unutulmuş bir kontrol yüzünden bütün program çöpe atılmamalıdır.
  2. Java'da Null baştan savmadır. Çoğu zaman Null kullanmak bir şey ifade etmeyecektir ve bir dil bir şeyin Null olmasına izin veriyorsa herhangi bir şey böyle olabilir. Java programcıları bu tarz kontrollerde anlamsız ve riskli kontrollerle uğraşmak zorunda kalır ki bu zaman kaybıdır.
    Java:
    if (string == null || string.equals(""))
    Ayrıca C#'da bu tarz bir durum için String.IsNullOrEmpty fonksiyonu mevcuttur.
    C#:
    if (string.IsNullOrEmpty(str))
  3. Null, özel bir durumdur. Değer olmayan bir değer direkt olarak ona özel durumlar ve müdahaleler alınmasını gerektirir. Bu evrensel bir problemdir. Bir örnek olarak C++'da pointer kullandığımız bir örneğe bakalım.
    C++:
    char c = 'F';
    char *myChar = &c;
    std::cout << *myChar << std::endl;
    *myChar, orada pointer -mesela bellek adresi- bizi o char değerine yönlendiriyor. Derleyici de bunu kontrol ediyor yani aşağıdaki örnek derlenmeyecektir.
    C++:
    char *myChar = 1337; // compile hatası
    std::cout << *myChar << std::endl;
    1337 bir char için kesin mevcut bir adres olmadığı için derleme işlemi başarısız oluyor ve bu hatamızı programı çalıştırmadan fark edebiliyoruz. Fakat 0 kullandığımızda (C++'da Null) derleyici buna izin veriyor fakat programımız bu sefer bize runtime hatası veriyor.
    C++:
    char *myChar = 0;
    std::cout << *myChar << std::endl; // runtime hatası
    Bu durumun başlıca sebebi maddenin başında dediğim gibi Null'un özel bir durum olması ve derleyicinin bu tarz bir şeye izin vermesidir.
  4. Null özel bir durum demiş miydim? C yazanlarınız nul-terminated string kavramını duymuşlardır. Burada da ana fikir char olmayan bir formda char olması. C-string, sonu 0 (Nul) ile biten byte dizisidir.
    Kod:
    75  65  82  65  72  65  78  0
    K   A   R   A   H   A   N (NUL)
    Bu istisnadan dolayı sayılamayacak kadar çok hata yaşandı, API saçmalıklarından tutun güvenlik açıklarına kadar. Nul-terminated string, CS'in yaptığı en büyük hatalardan. The Most Expensive One-byte Mistake - ACM Queue
Bu soruya daha onlarca cevap verilebilir hatta kendiniz de araştırabilirsiniz. Mesajımı çok uzun tutmamak adına bu kadar ekliyorum ve sıradaki sorunuzu cevaplamak istiyorum.
Optional üzerinde de kullanmadan önce kontrol yapman gerekiyor, aksi takdir de get methodu hata verdirecektir (o verdirmese zaten yine NPE verecek), NPE'ye benzer bana kalırsa? Senin dediğin gibi lambda ve streamlerde kullanılabilir, orElse sayesinde varsayılan değer ile birlikte vesiare kullanılabilir, fakat null'un yerini almaz ve "null kullanılmaması için" sadece bu yeterli bir sebep değildir.
Optional veya herhangi bir referans objesi kullanırken kontrolü kendimiz yapmak yerine direkt objenin kendisine yaptırabiliyoruz. Bahsettiğiniz fonksiyon isPresent ve bunu kullanmak iyi bir kodlama pratiği değildir. Bu yüzden ifPresent fonksiyonunu lambda ve monad ile kullanarak daha fonksiyonel bir koda sahip olabilirsiniz.

Neden bütün kontrolleri derleyici yapabilirken nereye Null kontrolleri eklememiz gerektiğini hatırlamak zorunda kalalım ki? Bana kalırsa bu cümle bütün olayı özetliyor, hatırlarsanız yukarıda pointer ile ilgili bir örnek vermiştim Null'un özel durum olmasıyla alakalı ve derleyicinin bunu kontrol etmeyişini. Bundan ötürü Optional veya referans objeleri kullanmak kodlamayı çok daha kolay hale getirecektir ve önemli bir pratiktir. Optional kullanarak aldığınız her normal referans başarılıdır ve sadece kendisini bir şeye eşitlemeyi unuttuysanız hata verir. Bu sebepten dolayı sürdürülebilirlik açısından da Optional kullanmak en doğru hamledir.

Nullable notu koyduğunda ve IDE'n de gerekli eklenti yüklü ise (yukarıda belirtmiştim) sen unutsan bile sana uyarı veriyor zaten. Kaldı ki çoğu zaman sen @Nullable yazmasan bile IDE ve yüklediğin diğer araçlar sana gerekli uyarıları sağlıyor (@Nullable yok fakat null döndürdün vb şeklinde). Bunlara ek olarak yeteri kadar test classı açarak test yapmak bu işin gerçek çözümüdür. Kaçamak yöntemler belirli durumlarda iyi olabilir (hatta kendi kullanım alanları vardır) fakat bu null'un tamamen kötü ve gereksiz olduğu anlamına gelmez; null kullanmıyorsanız hiç NPE almazsınız diye bir şey de yoktur, dışardan (illa bir ek kütüphane olmasına gerek yok) aldığınız herhangi bir veri her zaman null olabilir, buna Java'nın standart methodlarından bazıları da dahil. Null olamayacak tek şey primitive typelar'dır ve bunlarında default değerleri vardır, 0 dır çoğunun ki. Mesela bir Integer'ı int'e dönüştürdüğün de eğer 0 alıyor isen bunun Integer'ın gerçek değeri olan 0 mı yoksa null olduğu için mi 0 olduğunu anlayamazsın. Geri Integer'a çevirir isen de 0 olacaktır.
IDE için değil gerekli eklentinin koduna erişen herkeste yüklü olmasını ummak, IDE kullanmasını beklemek bile doğru bir hareket değildir. Tümleşik geliştirme ortamlarının yazılım ile doğrudan alakası yoktur, kod yazmak için zorunlu bir araç değildir. Bu forumda dahi sadece vim veya başka yazı editörleri ile kod yazan onlarca kişi bulabilirsiniz ki ben de onlardan birisiyim. Java ile yaptığınız uygulamayı düzenleyen, derleyen ve çalıştıran bir kişinin sahip olması gereken iki şey JRE ve JDK'dır ve bunun bilincinde olarak yazmalısınız. Lütfen herkesin sizin kullandığınız araçları kullanması gerektiği gibi amatörce bir hataya düşmeyin keza bunlar direkt kişisel seçimlerdir ve kaynak kodu paylaşırken dahi IDE/Editör gibi kullanılmış araçların konfigürasyonları paylaşılmaz.

Uzun lafın kısası, Optional kullanmak iyi bir pratiktir ve OOP konseptine çok daha yakındır. Sürdürülebilirlik açısından da daha başarılıdır, karşınızdaki kişinin Nullable notlarınızı görme ihtimali, fonksiyonunuzun döndürdüğü Optional objesini görmesinden düşüktür. Optional kullanmanın birçok artısı varken Null kullanmanın aşağıda yazacağım çok istisnai bir durum haricinde faydası yoktur. Nasıl ki "10 > 0" kesinlikle doğru bir önermeyse; birden fazla avantajı olan Optional, kayda değer hiçbir avantajı olmayan Null'dan daha iyidir ve aksi kötü bir pratiktir, kısa ve net.

Eğer CPU döngülerinizi daha efektif kullanmak istiyorsanız ve çok az bir performans için kod kalitesinden feragat ediyorsanız Null, C gibi düşük seviyeli dillerde kullanılabilir fakat halihazırda Java gibi yüksek seviyeli bir dil kullanıyorsanız böyle bir endişeniz olmamalı. Kodda Null kullanımı ile ilgili bir hata olduğunda bunu kodu çalıştırdığınızda veya IDE'de değil, derleyici üzerinde görmelisiniz ki Optional bunu sağlar.
 
Son düzenleme:

LifeMCServer

Nether Yerlisi
Mesajlar
2,410
En iyi cevaplar
98
Beğeniler
2,461
Puanları
10,250
Ruh hali
Ben "null kullanmayın kullandırtmayın" derken kimseye gidip milletin kafasını eze eze "kullanmayacaksınlan!" tarzında bir şey demedim. Ortada bir konu var ve ben doğru bulduğum inandığım şeyi kanıtlarıyla ve bu alanda ileri gelenlerinde doğru bulduğunu belirttim. Megacrafter adındaki arkadaş ile gayet doğru düzgün bir tartışma içerisindeyken cevap veremediğinden olsa gerek işi saçma bir yöne çekti neymiş "Yıllardır yazılımcıların değişik değişik şeylere düşmanlık etmesini hala anlayamıyorum.". Ben ve benim gibiler konuyu falan baltalıyormuş? Şu hastalıklı zihniyetten çıkın artık sizin doğru bulduğunuz şeylerin doğru olmadığını söyleyen insanlara saldırmak yerine "hayır kardeşim senin dediğin yanlış çünkü bla bla bla" diyerek cevap verirsen zaten karşındaki de senin söylediklerinin aksini iddia edebiliyorsa düzgün bir şekilde açıklar. Son olarak söylüyorum kimseye saldırmadım açıklayarak durumu sundum ve buna rağmen konuyu kirlettiğim falan söyleniyor. Konuyu kirletmek?? Muhtemelen herkesin size öpücük vermesini falan bekliyorsunuz. Daha cevap vermeyeceğim örümcek ağlarınızla mutlu günler dilerim.

Ortada bir konu var ve ben doğru bulduğum inandığım şeyi kanıtlarıyla ve bu alanda ileri gelenlerinde doğru bulduğunu belirttim.

İleri gelenler insan üstü varlık falan mı, arkadaşlarına ileri gelenler mi diyorsun :D Egoistlik iyidir falan da dersin şimdi. Bir tartışma da herkes eşittir, kim ileri gelen? Google'dan fikrini destekleyecek 2-3 makale bulup bu adam büyük (?) adam bu ne derse doğrudur demekle olmuyor. Aslında biliyor musun sizin asıl amacınız bu zaten. İnsanları ayırmak bölmek gruplandırmak. Her neyse oraya girmeyeyim yine tartışma uzar şimdi.

Megacrafter adındaki arkadaş ile gayet doğru düzgün bir tartışma içerisindeyken cevap veremediğinden olsa gerek işi saçma bir yöne çekti neymiş "Yıllardır yazılımcıların değişik değişik şeylere düşmanlık etmesini hala anlayamıyorum.".

Hallah hallah ya o mu cevap veremediğinden konuyu dağıtmış? Bana kalırsa daha çok sen cevap veremediğinden arkadaşlarını çağırmışsın. Sessiz sedasızdın ne oldu konuşmaya mı karar verdin?

Ben ve benim gibiler konuyu falan baltalıyormuş? Şu hastalıklı zihniyetten çıkın artık sizin doğru bulduğunuz şeylerin doğru olmadığını söyleyen insanlara saldırmak yerine "hayır kardeşim senin dediğin yanlış çünkü bla bla bla" diyerek cevap verirsen zaten karşındaki de senin söylediklerinin aksini iddia edebiliyorsa düzgün bir şekilde açıklar.

Kim konu baltalıyorsunuz dedi? Ben sadece kendimi de dahil ederek (suçlayarak) konunun kirlendiğini ve bir noktada durması gerektiğini söyledim.

Benim lafımı bana mı söylüyorsun nedir durum. "null kötüdür kullanmayın kullandırtmayın" yerine ilk mesajında açıklasaydın diye ilk mesajımda belirtmiştim ben zaten, şimdi de çıkıp bana sanki ben "null iyidir kullanın kullandırtın bu arkadaşa bakmayın" diye sana cevap vermişim gibi nedenini açıklasaydın diyorsun, he valla ya biz 2 sayfadır boşuna tartışıyoruz ortada neden meden yok :D

Daha cevap vermeyeceğim örümcek ağlarınızla mutlu günler dilerim.

Yukarıda da kaç kez daha uğraşmayacağım daha fazla kirletmeyelim tarzı cümleler kuruldu ama bak hala devam ediyor tartışma? Tartışmalar tek taraflı gitmez tek taraflı da bitmez. Herkes bıkana veya memnun olana kadar devam eder.

Hadi hadi cevap verirsin yine yaparsın sen. Bak bunu yazdım ya inadına kendini tutarsın falan şimdi.
 

LifeMCServer

Nether Yerlisi
Mesajlar
2,410
En iyi cevaplar
98
Beğeniler
2,461
Puanları
10,250
Ruh hali
Kendimi tam olarak ifade edememişim galiba, sorularınıza kısa ve spesifik yanıtlar vereceğim o halde. Konunun daha fazla kirlenmemesi ve amacından çıkmaması adına başka bir sorunuz olursa bana özel mesaj yoluyla ulaşmaktan çekinmeyin.

Null; değer olmayan bir değerdir. Bu cümle dahi Java gibi OOP bir dilde böyle bir tanımı kullanışsız yapar. İsterseniz örneklendirelim:
  1. Java'da Null, obje tipinin üzerine yazar bu da NPE gibi hatalara yol açar. Son kullanıcıya dağıtılmış bir yazılımda böyle bir hatanın kesinlikle alınmaması gerekir, aksine hatalar kontrol edilmeli ve unutulmuş bir kontrol yüzünden bütün program çöpe atılmamalıdır.
  2. Java'da Null baştan savmadır. Çoğu zaman Null kullanmak bir şey ifade etmeyecektir ve bir dil bir şeyin Null olmasına izin veriyorsa herhangi bir şey böyle olabilir. Java programcıları bu tarz kontrollerde anlamsız ve riskli kontrollerle uğraşmak zorunda kalır ki bu zaman kaybıdır.
    Java:
    if (string == null || string.equals(""))
    Ayrıca C#'da bu tarz bir durum için String.IsNullOrEmpty fonksiyonu mevcuttur.
    C#:
    if (string.IsNullOrEmpty(str))
  3. Null, özel bir durumdur. Değer olmayan bir değer direkt olarak ona özel durumlar ve müdahaleler alınmasını gerektirir. Bu evrensel bir problemdir. Bir örnek olarak C++'da pointer kullandığımız bir örneğe bakalım.
    C++:
    char c = 'F';
    char *myChar = &c;
    std::cout << *myChar << std::endl;
    *myChar, orada pointer -mesela bellek adresi- bizi o char değerine yönlendiriyor. Derleyici de bunu kontrol ediyor yani aşağıdaki örnek derlenmeyecektir.
    C++:
    char *myChar = 1337; // compile hatası
    std::cout << *myChar << std::endl;
    1337 bir char için kesin mevcut bir adres olmadığı için derleme işlemi başarısız oluyor ve bu hatamızı programı çalıştırmadan fark edebiliyoruz. Fakat 0 kullandığımızda (C++'da Null) derleyici buna izin veriyor fakat programımız bu sefer bize runtime hatası veriyor.
    C++:
    char *myChar = 0;
    std::cout << *myChar << std::endl; // runtime hatası
    Bu durumun başlıca sebebi maddenin başında dediğim gibi Null'un özel bir durum olması ve derleyicinin bu tarz bir şeye izin vermesidir.
  4. Null özel bir durum demiş miydim? C yazanlarınız nul-terminated string kavramını duymuşlardır. Burada da ana fikir char olmayan bir formda char olması. C-string, sonu 0 (Nul) ile biten byte dizisidir.
    Kod:
    75  65  82  65  72  65  78  0
    K   A   R   A   H   A   N (NUL)
    Bu istisnadan dolayı sayılamayacak kadar çok hata yaşandı, API saçmalıklarından tutun güvenlik açıklarına kadar. Nul-terminated string, CS'in yaptığı en büyük hatalardan. The Most Expensive One-byte Mistake - ACM Queue
Bu soruya daha onlarca cevap verilebilir hatta kendiniz de araştırabilirsiniz. Mesajımı çok uzun tutmamak adına bu kadar ekliyorum ve sıradaki sorunuzu cevaplamak istiyorum.

Optional veya herhangi bir referans objesi kullanırken kontrolü kendimiz yapmak yerine direkt objenin kendisine yaptırabiliyoruz. Bahsettiğiniz fonksiyon isPresent ve bunu kullanmak iyi bir kodlama pratiği değildir. Bu yüzden ifPresent fonksiyonunu lambda ve monad ile kullanarak daha fonksiyonel bir koda sahip olabilirsiniz.

Neden bütün kontrolleri derleyici yapabilirken nereye Null kontrolleri eklememiz gerektiğini hatırlamak zorunda kalalım ki? Bana kalırsa bu cümle bütün olayı özetliyor, hatırlarsanız yukarıda pointer ile ilgili bir örnek vermiştim Null'un özel durum olmasıyla alakalı ve derleyicinin bunu kontrol etmeyişini. Bundan ötürü Optional veya referans objeleri kullanmak kodlamayı çok daha kolay hale getirecektir ve önemli bir pratiktir. Optional kullanarak aldığınız her normal referans başarılıdır ve sadece kendisini bir şeye eşitlemeyi unuttuysanız hata verir. Bu sebepten dolayı sürdürülebilirlik açısından da Optional kullanmak en doğru hamledir.


IDE için değil gerekli eklentinin koduna erişen herkeste yüklü olmasını ummak, IDE kullanmasını beklemek bile doğru bir hareket değildir. Tümleşik geliştirme ortamlarının yazılım ile doğrudan alakası yoktur, kod yazmak için zorunlu bir araç değildir. Bu forumda dahi sadece vim veya başka yazı editörleri ile kod yazan onlarca kişi bulabilirsiniz ki ben de onlardan birisiyim. Java ile yaptığınız uygulamayı düzenleyen, derleyen ve çalıştıran bir kişinin sahip olması gereken iki şey JRE ve JDK'dır ve bunun bilincinde olarak yazmalısınız. Lütfen herkesin sizin kullandığınız araçları kullanması gerektiği gibi amatörce bir hataya düşmeyin keza bunlar direkt kişisel seçimlerdir ve kaynak kodu paylaşırken dahi IDE/Editör gibi kullanılmış araçların konfigürasyonları paylaşılmaz.

Uzun lafın kısası, Optional kullanmak iyi bir pratiktir ve OOP konseptine çok daha yakındır. Sürdürülebilirlik açısından da daha başarılıdır, karşınızdaki kişinin Nullable notlarınızı görme ihtimali, fonksiyonunuzun döndürdüğü Optional objesini görmesinden düşüktür. Optional kullanmanın birçok artısı varken Null kullanmanın aşağıda yazacağım çok istisnai bir durum haricinde faydası yoktur. Nasıl ki "10 > 0" kesinlikle doğru bir önermeyse; birden fazla avantajı olan Optional, kayda değer hiçbir avantajı olmayan Null'dan daha iyidir ve aksi kötü bir pratiktir, kısa ve net.

Eğer CPU döngülerinizi daha efektif kullanmak istiyorsanız ve çok az bir performans için kod kalitesinden feragat ediyorsanız Null, C gibi düşük seviyeli dillerde kullanılabilir fakat halihazırda Java gibi yüksek seviyeli bir dil kullanıyorsanız böyle bir endişeniz olmamalı. Kodda Null kullanımı ile ilgili bir hata olduğunda bunu kodu çalıştırdığınızda veya IDE'de değil, derleyici üzerinde görmelisiniz ki Optional bunu sağlar.

Java'da Null, obje tipinin üzerine yazar bu da NPE gibi hatalara yol açar. Son kullanıcıya dağıtılmış bir yazılımda böyle bir hatanın kesinlikle alınmaması gerekir, aksine hatalar kontrol edilmeli ve unutulmuş bir kontrol yüzünden bütün program çöpe atılmamalıdır.

JVM'de NPE'yi kapatma ayarı olsa NPE'yi kapatırdınız sanırım. Hatalar kontrol edilmeli diyorsun sonra unutulmuş bir kontrol yüzünden bütün program çöpe atılmamalı diyorsun. Doğru düzgün bir uncaught exception handler kullanır isen yakalamadığın hatalar dahil hepsini kontrol edebilir raporlayabilirsin. Null olan bir şeye erişmeye çalışman senin hatandır ve NPE bu hatayı sana bildirir. Null kullanmayıp alternatif yöntemler kullanmak ise (ki bunlar nullu tamamen yok etmez sadece null yerine kullanılabilecek, belkide daha iyi alternatiflerdir, kullanım alanları farklıdır, bunu kaç kez söyledim bilmiyorum) tamamen bu NPE den kaçmaktır. Tek amacın programın çökmesini engellemek ise bu bu sorun için saçma bir yol.

Java'da Null baştan savmadır. Çoğu zaman Null kullanmak bir şey ifade etmeyecektir ve bir dil bir şeyin Null olmasına izin veriyorsa herhangi bir şey böyle olabilir. Java programcıları bu tarz kontrollerde anlamsız ve riskli kontrollerle uğraşmak zorunda kalır ki bu zaman kaybıdır.

C#'da sadece isNullOrEmpty değil daha birçok ekstra özellik var. Conditional expression sayesinde bu null checklerine gerek kalmıyor direk örneğin null olabilecek değişkenin sonuna ? koyup field / method ne yapacaksan yapıyorsun. Null gereksiz ise neden conditional expression diye bir şey var? Hadi null'u hata yaptılar eklediler (ekleyen arkadaş Elfen'in aile dostuymuş galiba), bunu da kazara mı eklediler :D

Conditional expression dışında Struct'lar var, non-null oluyorlar varsayılan olarak, basit classlar için daha hızlı çalışıyor, type isminin sonuna ? koyarak nullable yapabiliyorsun tabii.

Null, özel bir durumdur. Değer olmayan bir değer direkt olarak ona özel durumlar ve müdahaleler alınmasını gerektirir. Bu evrensel bir problemdir. Bir örnek olarak C++'da pointer kullandığımız bir örneğe bakalım.

Bir şeyi kullanır iken dikkatli olmamız gerekiyor ise veya hata alma ihtimalimiz var ise o şey neden kötü (problemli) olsun? (bilmek ister isen problemli olan null veya java değil senin yazdığın koddur, hatada senindir, kodda) Null özel bir durumdur diyorsun ve zaten tartıştığımız konu özel durumlarda hata mı verdirelim null mu döndürelim tarzı bir şeydi. Hata verdirmek methodu çağıran kişinin programının çökmesine (sizin de dediğiniz gibi?) yol açabilir (eğer try catch yapmamış ise), checked exception kullanır isekte catch yapmaya zorlarız hata vermeyeceğinden emin ise bile boşuna neden catchlesin? Null objeye gelir isek null'u temsil eden sabit evrensel bir değer var iken neden yeni class açıp onun instancesini oluşturayım? NPE'den kurtulmak için mi, null-check ten zaman kazanmak için mi yoksa bir dakika.. Programın çökmesini engellemek için mi? Hadi tamam fakat bu sadece bir yöntem. Null'u tamamen yok eden yerine geçen bir şey değil. Optional da aynı şekilde.

IDE için değil gerekli eklentinin koduna erişen herkeste yüklü olmasını ummak, IDE kullanmasını beklemek bile doğru bir hareket değildir. Tümleşik geliştirme ortamlarının yazılım ile doğrudan alakası yoktur, kod yazmak için zorunlu bir araç değildir. Bu forumda dahi sadece vim veya başka yazı editörleri ile kod yazan onlarca kişi bulabilirsiniz ki ben de onlardan birisiyim. Java ile yaptığınız uygulamayı düzenleyen, derleyen ve çalıştıran bir kişinin sahip olması gereken iki şey JRE ve JDK'dır ve bunun bilincinde olarak yazmalısınız. Lütfen herkesin sizin kullandığınız araçları kullanması gerektiği gibi amatörce bir hataya düşmeyin keza bunlar direkt kişisel seçimlerdir ve kaynak kodu paylaşırken dahi IDE/Editör gibi kullanılmış araçların konfigürasyonları paylaşılmaz.

Ben sadece işimizi kolaylaştıran araçlara örnek verdim. Null'u eleştirir iken savunduğunuz şey "npe'yi çözerek zaman kaybediyoruz, null check ekleyerek zaman kaybediyoruz" fakat şimdi de çıkıp notepad kullananları da düşünmelisiniz diyorsun. Madem hız senin için bu kadar önemli neden işlerini kolaylaştıran programlar, araçlar ile işlerini halletmiyorsun? Bu arada bu IDE ve araçlar için bunlar kişisel seçim değildir'i nerede demişim bana bunu gösterir misin? Nerede çıkıp da ben "IDE yerine sakın Notepad kullanmayın kullandırtmayın, kötüdür aman ha!" demişim? :D

Sizin için 10 nasıl 0 dan büyük ise null kullanmamak ta o kadar doğruysa diyecek fazla bir şey yok. Konu zaten sizin için kapanmış. Siz kendinizi Elfen'in dediği gibi sanırım ileri gelenler olarak görüp bizleri "eğitmeye" çalıştığınızı falan sanıyorsunuz. (en azından diğer arkadaş)
 

Üst