Null kısıtlama ve null izinli tipler
(bugs.openjdk.org)- Java, tiplere nullness marker ekleyerek
Foo!ilenull'ı reddeden,Foo?ile ise bilerek izin veren bir preview language feature hazırlıyor - İşaretsiz
Foo, nullness'i unspecified olarak bırakıyor ve mevcut kodla uyumluluğu koruyor; nullness'i farklı tipler arasında dönüşüm uyarı veya çalışma zamanı denetimi içerebiliyor null'ı reddeden alanlar ve diziler varsayılan değer olaraknullkullanamadığı için, örnek alanlarısuper(...)çağrısından önce kesin olarak atanmalı ve diziler için bileşen başlangıç değeri gereklinull,Foo!'a daraltılırsaNullPointerExceptionoluşuyor; dizi ve alan yazma yollarında ise kirlenmeyi önlemek için ArrayStoreException ve FieldStoreException kullanılıyor- Valhalla'nın value class flattening gibi optimizasyonları,
nulldışlamasını güvenilir kılan temeli sağlıyor; standart kütüphaneye uygulama veya mevcut kodu otomatik yeniden yorumlama şu anki hedefler arasında değil
Java tiplerinde nullness'i açıkça belirten preview özelliği
- Java tiplerine nullness marker eklenerek tipin değer kümesine
null'ın dahil olup olmadığı ifade ediliyor Foo!, null-restricted tiptir ve değer kümesindennull'ı çıkarırFoo?, nullable tiptir ve değer kümesinenull'ı bilerek dahil eder- İşaretsiz
Foo, nullness'i unspecified bırakır;nulloluşabilir ama bunun kasıtlı olup olmadığı bilinmez - Bu özellik, derleme ve çalışma zamanında
--enable-previewbayrağıyla etkinleştirilen bir preview feature'dır
Hedefler ve hedef dışı konular
- Java referans tiplerinin
nullbekleyip beklemediğini ifade etmek ve nullness'i farklı tipler arasındaki dönüşümlerde uyarı ile denetim sağlamak - Mevcut Java koduyla uyumlu olmak ve kaynak ya da ikili uyumsuzluk oluşturmadan kademeli olarak devreye alınabilmek
null'ı reddeden tipteki değişkenlerin ilk okunmadan önce başlatılmasını zorunlu kılmak ve ayrı derlenmiş sınıflarda da çalışma zamanındanullreddini uygulamak- Valhalla'nın value class flattening'i gibi çalışma zamanı optimizasyonlarının null kısıtlı tiplere güvenebilmesi için metadata ve bütünlük güvencesi sağlamak
- Şu anda hedeflenmeyenler:
- Mevcut kodu otomatik olarak yeniden yorumlamamak
- Olası tüm
nulldurumlarını derleme hatasına dönüştürmemek intgibi primitive tiplere nullable biçim eklememek- Bu aşamada dil genişlemesini standart kütüphaneye uygulamamak
Neden gerekli
- Java'da
Stringdeğişkeni birStringnesne referansı ya danulltutabilir, ancak dil düzeyinde hangisinin amaçlandığını ifade etmenin yolu yoktur - Pek çok program
nullolmadığını varsayar, ancak bunu Javadoc sözleşmeleri ve uygulama kodunda tutarlı biçimde zorunlu kılmak ek çaba gerektirir - Bu beklenti bozulduğunda
nulldeğeri uygulama kodunun içine sızıp asıl hatadan oldukça uzakta bir noktada istisna üretebilir - Geliştirici, tipin bir parçası olarak
null'ı reddetme veya kabul etme niyetini ifade ederse, derleme zamanı geri bildirimi ve çalışma zamanı denetimleri beklenmediknull'ları daha erken bulmaya yardımcı olur - Valhalla'da value class tipindeki değişkenler değerin flattened representation'ı ile optimize edilebilir; ancak
nullkodlaması için ek bit gerekirse bellek kullanımı artabilir veya depolama optimizasyonu yapılamayabilir - Amber'da pattern matching adayının nullness'i,
switchiçin exhaustiveness değerlendirmesini etkileyebilir; tip deseninin nullness'i denullile eşleşip eşleşmeyeceğini etkileyebilir
Nullness marker sözdizimi ve tip yapısı
- Nullness, tipin ayrılmaz bir parçası sayılır;
Foo?ileFoo, nullness'leri farklı olduğu için farklı tiplerdir - Hem dizi tipi hem de dizi bileşen tipi nullness marker taşıyabilir
Foo?[]!, dizinin kendisinin null-restricted, bileşenlerinin ise nullableFooolduğu bir tiptir- Çok boyutlu dizilerde her köşeli parantez çiftinin ardından marker konabilir; geleneksel olarak soldan sağa, dıştan içe yorumlanır
- Parametreli tipler ve tip argümanları da nullness marker taşıyabilir
Predicate!<Foo?>, null-restricted birPredicate'tir ve tip argümanı nullableFoo'dur
- Null kısıtlı ya da null izinli tipi ifade etmek için kaynakta
!veya?açıkça bulunmalıdır - Gelecekte, bir sınıf ya da derleme birimindeki tüm tiplerin varsayılan olarak null-restricted yorumlanıp yalnızca
?'ın istisna olarak kullanılması değerlendirilebilir; ancak ayrıntılar ayrı bir çalışmadır
Alan ve dizi başlatma kuralları
- Mevcut Java'da referans tipli alanların ve dizi bileşenlerinin varsayılan değeri
null'dır, ancak bu değer null-restricted alanlar veya dizi bileşenleri için uygun değildir - Null-restricted alanlar ve diziler, okunmadan önce program tarafından her zaman başlatılmalıdır
- Null-restricted örnek alanının initializer'ı yoksa, her constructor'da açık ya da örtük
super(...)çağrısından önce definite assignment yapılmalıdır- Flexible Constructor Bodies JEP, constructor'ın başında gerekli başlatma kodunun yazılmasına izin verir
- Bu early construction context içinde
this'e başvurmak veya başlatılmamış alanları okuma riski taşıyan işlemler yasaktır
- Null-restricted örnek alanında initializer varsa, her constructor başlangıcında
super(...)çağrısından önce çalıştırılırthis(...)çağıran constructor, mevcut kurallarda olduğu gibi initializer çalıştırmayan özel durumdur
- Null-restricted static alanlar, sınıfın tüm static initializer'ları ve başlatma blokları bittiğinde definite assignment almış olmalıdır
- Başka bir sınıf, sınıf başlatması sırasında bu alanı okumaya çalışırsa çalışma zamanı denetimi erken okumayı saptar ve istisna fırlatır
- Bileşen tipi null-restricted olan dizilerde, dizi oluşturma ifadesi her bileşen için başlangıç değeri sağlamalıdır
- Dizi initializer'ı ile tüm değerler tek tek yazılabilir
- Yeni bir kısaltılmış sözdizimi de mümkün, ancak sözdizimi henüz TBD
İfade nullness'i ve nullness dönüşümleri
- Java derleyicisi tip denetimi sırasında her ifadenin nullness'ini belirler
- Değişken başvurusunun nullness'i değişken bildiriminden, metot çağrısının nullness'i ise başvurulan metodun dönüş tipinden gelir
nullliteral'i nullable'dır- Diğer referans tipli ifadelerin çoğu null-restricted'dır
- Buna literal'ler, string birleştirme,
this, sınıf örneği oluşturma, dizi oluşturma, method reference ve lambda ifadeleri dahildir
- Buna literal'ler, string birleştirme,
- Nullness dönüşümü; atama, çağrı ve cast bağlamlarında izinlidir
- Genişletici nullness dönüşümleri şunları içerir:
Foo!→Foo?Foo!→ unspecifiedFooFoo?→ unspecifiedFoo- unspecified
Foo→Foo?
- Daraltıcı nullness dönüşümleri şunları içerir:
Foo?→Foo!- unspecified
Foo→Foo!
- Daraltıcı nullness dönüşümleri, unboxing dönüşümüne benzer biçimde derleyici tarafından otomatik yapılır; ancak çalışma zamanında dinamik denetim yapılarak
NullPointerExceptionüretilebilir nullliteral'ini doğrudan null-restricted tipe dönüştürme girişimi derleme zamanı hatasıdır
Çalışma zamanı denetimleri ve istisnalar
- Çalışma zamanında
nulldeğeri, null-restricted tipe daraltıcı nullness dönüşümünden geçerse NullPointerException oluşur - Kaynak kodda açıkça görünmeyen daraltıcı nullness dönüşümleri de çalışma sırasında ortaya çıkabilir
- Bileşen tipi null-restricted olan bir dizi, kaynak kodda daha az spesifik bir tip olarak ele alınsa bile normal dizi depolama denetiminde
nulldeğerini reddeder- Bu dönüşüm başarısızlığı ArrayStoreException üretir
- Derleme zamanında null-restricted olmayan bir alan, daha sonra ayrı bir derlemeyle null-restricted olursa yeni field store check
nulldepolamayı reddeder- Bu dönüşüm başarısızlığı FieldStoreException üretir
- Override ilişkisindeki metot çağrılarında, üst metodun parametre çağrı tipine dönüşümün ardından overriding metodun parametre tipine dönüşüm gelebilir
- Metot dönüş değeri de önce bildirilen metot dönüş tipine, ardından çağrı noktasının beklediği dönüş tipine dönüştürülebilir
Generics, tip argümanları ve overriding
- Type variable kullanımlarına da nullness marker eklenebilir;
T!null-restricted,T?ise nullable tiptir - Null-restricted ve nullable type variable tipleri, generic kod içinde belirli bir nullness'i ileri sürer
- Tip argümanı olarak kullanılan tipler de nullness ifade edebilir; type variable type üzerindeki nullness marker, tip argümanında ileri sürülen nullness'in üzerine yazar
- Generic API'nin erased implementasyonu içinde null kısıtlaması uygulanamaz
- Ancak generic API sınırlarında ortaya çıkan normal örtük cast'ler, çalışma zamanında null-restricted tip argümanlarını uygular
- Birlikte çalışabilirlik için tip argümanları içindeki nullness güçlü biçimde zorlanmaz
Predicate<String!>;Predicate<String>ya daPredicate<String?>tipine dönüştürülebilir- Bu tür unchecked nullness conversion işlemleri uyarı üretebilir
- Dizi bileşen tipinin nullness'ini değiştirmek de unchecked nullness conversion olarak izinlidir; hangi koşullarda çalışma zamanı denetimi yapılacağı henüz TBD
- Metot signature eşdeğerliği değerlendirilirken nullness göz ardı edilir
- Parametre ve dönüş tiplerinin nullness'i uyuşmasa da bir metot diğerini override edebilir
- Farklı API'ler nullness marker'ları bağımsız olarak benimserse bu tür uyuşmazlıklar yaygın olabilir
- Nullness, metodun uygulanabilirliğini etkilemez ve tip argümanı çıkarımının başarısız olmasına yol açmaz; ancak generic metodun dönüş tipi için çıkarılan nullness'i etkileyebilir
- Çıkarım algoritmasının ayrıntıları TBD
Derleyici uyarıları ve hatalar
- Bir tipi null-restricted yapmak yeni derleme zamanı hataları doğurabilir
- O tipteki alan veya diziler başlatılmamışsa
nullliteral'i o tipe dönüştürülmeye çalışılıyorsanullliteral'inin null-restricted tipteki ifadeyle karşılaştırılması da derleme zamanı hatası olabilir
- Bunun dışındaki durumlarda nullness analizi yardımcı niteliktedir ve derleme zamanı hatası üretmez
javac, çalışma zamanı hatalarını önlemeye yardımcı olmak için uyarılar sağlar; IDE'ler ve diğer analiz araçları için de aynı yaklaşım önerilir- Olası uyarı nedenleri:
?tipinden gelen durumlar dahil daraltıcı nullness dönüşümleri?tipli ifadelerin üye erişimi veya diğer null-hostile işlemlerde kullanılması- Tip argümanlarının nullness'inin bound ile tutarsız olması
- Metot parametresi ya da dönüş nullness'inin override edilen metotla uyuşmaması
- Tipin nullness'ini değiştiren unchecked conversion işlemleri
Class file, reflection ve yardımcı değişiklikler
- Null marker kullanımının çoğu
classdosyasında silinir; buna eşlik eden çalışma zamanı dönüşümleri ise doğrudan bytecode içinde ifade edilir Signatureözniteliğinin sözdizimi, tip içinde!ve?kullanımına izin verecek şekilde güncellenir- Nullness, metot ve alan descriptor'larında kodlanmaz
- Alan kirlenmesini önlemek için yeni
NullRestrictedözniteliği, alanınnulldeğere izin vermediğini belirtir- Bu alan aynı zamanda
ACC_STRICTişaretini de taşımalıdır ve strict initialization uygulanmalıdır - Doğrulayıcı, constructor
super(...)çağrısı yaptığında strict initialization gerektiren tüm örnek alanlarının atanmış olup olmadığını denetler - Alana yazma yönündeki her girişim
nulldeğerini kontrol eder ve bulunursaFieldStoreExceptionfırlatır
- Bu alan aynı zamanda
- Null-restricted dizi oluşturma,
anewarraykomutuyla desteklenmez; reflection API çağrısıyla yapılmalıdır Foo!.classya daFoo?.classliteral'i yoktur; bunlara karşılık gelen birjava.lang.Classörneği de bulunmaz- Yeni RuntimeType API, dizi ve alan depolama denetimlerinde çalışma zamanında uygulanan tip kümesini tanımlar ve tüm sınıf ile arayüz tiplerinin null-restricted varyantlarını içerir
FieldAPI, alanınRuntimeTypebilgisini sorgulamayı destekler; bu değergetTypesonucundan farklı olabilirArrayAPI, bileşen tipiniRuntimeTypeile ifade eden birnewInstancevaryantını destekler- Bu varyant, dizi bileşeni için başlangıç değeri verilmesine de izin verir
- Başlangıç değeri olmadan null-restricted dizi oluşturma girişimlerini reddeder
- Geleneksel deserialization, null-restricted alanlar ve dizilerle uyumlu değildir; ayrı bir JEP, başlatılmamış null-restricted alan ve dizileri açığa çıkarmayan bir serialization mekanizması sağlayacaktır
javadoctarafından üretilen belgeler nullness marker'larını içerirjava.lang.reflect.Typevejavax.lang.modelAPI'leri, tip gösteriminde nullness'i kodlar
Alternatifler ve bağımlılıklar
- Java ekosistemindeki çeşitli geliştirme araçları kendi derleme zamanı null izleme sistemlerini uyguladı; ancak Java dilini değiştirmedikleri için sözdizimi çoğunlukla annotation'larla sınırlı kaldı ve etkileyebildikleri davranış da derleme zamanı denetimleriyle sınırlı oldu
- Diğer diller nullness'i tip sisteminde izler; birçok dil varsayılan olarak null-restricted'dır ve açık null denetimi olmadan null-restricted tipe atamayı hata sayar
- Java'da bu özellik isteğe bağlı olmalı ve tek seferlik büyük bir geçiş gerektirmeden kademeli kullanılabilmelidir
- Çalışma zamanı nullness zorlaması, açık denetimler veya
Objects.requireNonNullçağrılarıyla da uygulanabilir- Ancak bunu tutarlı biçimde uygulamak zahmetlidir, ek belgelendirme gerektirir ve programın okunabilirliğini düşürür
- Alan ve dizi gibi değişken depolama alanlarına doğrudan uygulanabilecek bir yöntem yoktur
- Önkoşul, Flexible Constructor Bodies (Second Preview) özelliğidir
- Constructor'ın
super(...)çağrısından önce ifadeler çalıştırıp örnek alanlarına atama yapabilmesi, null-restricted alan başlatma gereksinimini mümkün kılar
- Constructor'ın
- Gelecek çalışmalar arasında şunlar bulunur:
- Null-Restricted Value Class Types (Preview): null-restricted value-class-typed alanlar ve diziler için kodlama optimizasyonu
- JEP 402: Enhanced Primitive Boxing (Preview): dilde örtük boxing dönüşümleri daha geniş kullanılırken nullness izleme
- JVM sınıf ve metot özelleştirmesi (JEP 218 ve revizyonları): bazı tip argümanlarının nullness'ini somutlaştırma ve uygulama
- Olası ek gelecekteki iyileştirmeler arasında standart API'nin bazı bölümlerine nullness marker uygulanması, bytecode'da daha kısa null check gösterimi, null-restricted metot parametreleri için daha güçlü düşük seviyeli zorlama ve belirli bağlamlardaki tüm tipleri örtük olarak null-restricted sayan dil mekanizmaları yer alır
1 yorum
Hacker News yorumları
Bu yaklaşımın birkaç yıl önce C#’ın benimsediği yöntemden farklı olması ilginç. C#’ta bir projede null kabul edilebilirliği açtığınızda, açıkça nullable olarak işaretlenmediği sürece tüm değişkenler non-null olarak bildirilir; bu öneride ise mevcut değişkenler fiilen nullable, açık nullable ya da açık non-nullable seçeneklerinden biri oluyor.
Kotlin de bir JVM dili, ancak C# gibi açıkça belirtilmediğinde non-null kabul ediyor; sadece Kotlin’in geriye dönük uyumluluk yükü yok.
lateinit varile non-nullable bir tipi başka bir metotta başlatılana kadar boş bırakabiliyor ve başlatmadan önce erişilirse özel bir istisna fırlatan bir geçici çözüm de sunuyor.Neden üç seçenek koyduklarını merak ediyorum. Açıklama eklenmemiş değişkenleri nullable tutup, yalnızca açıklama eklenmiş değişkenleri açık non-null yapmak olmaz mıydı diye düşünüyorum. Hiçbir işaret olmasa da otomatik olarak nullable ise, ayrıca nullable bildirmek istemek için bir neden aklıma gelmiyor.
C# yöntemini daha çok seviyorum, ama bu yöntemin avantajı, legacy kod tabanlarında null kabul edilebilirlik sorunlarının tamamını çözmeden kullanılabilmesi. Buna karşılık C# null kabul edilebilirlik sorunlarını hemen ortaya çıkarıyor; bu öneri ise şimdiye kadar olduğu gibi bunları saklı tutabiliyor.
Ayrıca “bir metot, parametrelerinin ve dönüş değerinin null durumları uyuşmasa da başka bir metodu override edebilir” kısmı garip. Bir callback’i override/implement ederken asıl metot non-null dönüş belirtmişken null döndüren bir ayağa sıkma durumuna dönüşecek gibi görünüyor.
Zaman nedeniyle şu anda birkaç kritik nokta dışında yalnızca açıklamaları açma yolunu seçtik, ama bilinçli karar verdiğimiz yerleri hemen görebilmek için JetBrains’in
NotNullAttributeveCanBeNullAttributedeğerlerini hâlâ işaret olarak tutuyoruz. İkincisi, nullable için açık işaret bulunduğundan kaldırılabilir; ancak birincisi C#’ın kendi özelliğiyle ad çakışması yaşıyor.Bu anlamda üç seçenek oldukça yerinde. Çünkü kod yüz binlerce satır olduğunda hızlı ve kolay geçiş yapmak zor.
Diğer iç projelerde, dokunduğumuz kodun çevresine
#nullable enableserpiştirerek null kabul edilebilirlik kapsamını kademeli genişletiyoruz. Yeni kodun nullable context içinde olması şartını da koyuyoruz. Bu da zaten açıklama eklenmiş kısımları belirtmek için fena değil, ancak çok daha küçük bir kod tabanı ve ekipte mümkün olan bir yöntem.String!gibi ünlem işaretiyle gösteriyor.“Platform tipi” terimi ve ünlem sembolü kafa karıştırıcı, ama bunun dışında Kotlin yaklaşımı oldukça iyi çalışıyor. Kotlin’de baştan beri null kabul edilebilirliği olduğu için programcılar platform tiplerini doğrudan belirleyemiyor; ancak JVM veya JavaScript gibi null kabul edilebilirliği belirsiz temel platformlarla uyumluluk için bunlar hâlâ gerekli.
Bu yaklaşımda varsayılan değer hâlâ makul. Varsayılan olarak her zaman non-nullable olmalı; aksini düşünen biri Tony Hoare’dan hiçbir şey öğrenmemiş demektir. Aynı zamanda geriye dönük uyumluluk da korunuyor. Kotlin için bu kolay taraftaydı; Java ve C# ise mevcut kaynak kodla uyumluluğu da korumak zorunda.
Ne Java yöntemi ne de C# yöntemi ideal. C# yöntemi, derleyici bayrağına göre kodun davranışını büyük ölçüde değiştiriyor; Java yöntemi ise varsayılanı en kötü seçenek haline getiriyor.
Yine de C# tarafına daha yakınım. Çünkü “muhtemelen null olabilir” seçeneğini en kolay seçenek yaparsanız çoğu programcı varsayılan olarak onu seçecektir. Özellikle Java gibi kurumsal dostu bir dilde bu daha da olası. Linter’lar ve derleyici uyarıları uzun vadede yardımcı olur, ancak Java kodunun çoğunda null kabul edilebilirliğinin düzgün açıklanması yıllar alacak gibi görünüyor. C# kullanıcıları kısa vadede daha çok acı çekecek, ama açık null kabul edilebilirliği hedefine çok daha hızlı ulaşma olasılıkları yüksek.
https://kotlinlang.org/docs/java-interop.html#null-safety-an...
https://www.infoq.com/presentations/Null-References-The-Bill...
T?’nin nullable,T!’nin non-nullable anlamına gelmesi ve yeni derlenen kaynaklarda normalTvarsayılanının kaynak dosyası bazında,package-infodosyası bazında veya derleyici anahtarıyla global olarak belirlenen pragma benzeri bir bildirim ile ayarlanmasıydı.Daha sonraki bir LTS Java sürümünde global varsayılan değiştirilebilirdi. Böylece proje geçişi kolaylaşır, pragma otomatik olarak eklenip/güncellenebilir ve gerekirse eski varsayılan da korunabilirdi.
Ayrıca mevcut JSR-305
@Nonnullaçıklaması, sınıf dosyalarında non-nullable tip görünümlerini ifade etme biçimi olarak kullanılsaydı, eski JDK’larla çift yönlü uyumluluk da sağlanabilirdi.!sembolünü yazmasına gerek kalmadan, belirli bir bağlamdaki tüm tiplerin örtük olarak null kısıtlı olduğunu dilin ifade etmesini sağlayan bir mekanizma sunma” diye bir bölüm var.Derleyici bayrağı ya da modül etiketi düzeyinde bir şey bile yeterli olabilir.
Yine de ayrıca belirtilmediğinde otomatik olarak non-nullable varsayan bir derleyici bayrağının geleceğini düşünüyorum.
İyi görünüyor. Sonunda dil düzeyinde binlerce gereksiz istisnayı ve null kontrolünü ortadan kaldırmanın bir yolu oluyor. Ancak null olup olmadığını daraltan otomatik dönüşüm yanlış hissettiriyor
Teklifteki örneklerde
String? id(String! arg) { return arg; },String s = null;,Object! o1 = s; // NPE,Object o2 = id(s); // NPE,Object o3 = (String!) s; // NPEiçin en azından ilk iki durumun derleme hatası olması gerekmez mi diye düşünüyorumSonuncusu açıkça belirtildiği için muğlak, ama bence
if (s != null)içinde derleyicinin etkin türüString!olarak bilipString! ss = s;ifadesine izin vermesi daha iyi olurdu. O zaman hata ihtimali olmazAslında son durumdaki cast yerine
Objects.requireNonNull(s)kullanmayı daha açık olduğu için tercih ederim. Yine de açık denetimi atlayıp yalnızca optimizasyon yüzünden engellenen durumları hariç tutanObjects.unsafeForceNonNull(s)gibi bir şey de olsa iyi olurdu. unsafe bir metot olursa, karmaşık statik analiz eklemeden doğrudanrequireNonNulluygulanabilirNe yazık ki bu yalnızca çalışma zamanında kontrol edilecek
Örneğin standart kütüphane en azından bir süre null türlere geçmeyeceğini açıkça belirtiyor
Paket düzeyinde ya da en azından dosya düzeyinde tüm değişkenleri varsayılan olarak non-null işaretlemenin bir yolu kesinlikle gerekli görünüyor. Aksi halde güvenlik için neredeyse tüm değişkenlerde
T!sözdizimini kullanma yönünde güçlü bir eğilim olur ve bu da çok fazla gürültü yaratır!işareti kullanmasına gerek kalmadan belirli bir bağlamdaki tüm türlerin örtük olarak null ile sınırlandırıldığını dilin beyan etmesini sağlayan bir mekanizma sunmak” yer alıyor@Nullile anotasyon eklemek gerekiyorSorun yalnızca kütüphanelerle etkileşilen kod sınırlarında çıkıyor. Bu yeni sözdizimi de benzer olacak gibi
“Şimdilik dil iyileştirmelerini standart kütüphaneye uygulamak hedef değil” kısmı üzücü
Mecburen PHP kullanmış biri olarak, veriler hakkında önceden garanti altına aldığın özellikleri devasa standart kütüphaneyle her etkileşimde soyup tekrar kurmak zahmetli
Java’nın da bu ifade gücünü standart kütüphaneye daha aktif biçimde koyup birinci sınıf vatandaş yapması gerekiyor
Optionalkullanan legacy kod, açık nullable/non-nullable önerisi için yük oluyor. Record türleri de varsayılan olarak non-nullable olabilirdi diye düşünüyorumAyrıca iki aşamaya bölmek, bu özelliği preview özellik olarak daha kolay yayımlayıp geri bildirim aldıktan sonra tasarımı kesinleştirmeyi sağlar. Hepsini tek seferde yapmaya çalışırsan özelliği gerçekten yineleyerek iyileştirme alanı neredeyse kalmaz
Bu özelliğin Java’ya gelmesini isterim.
T?gibi dil düzeyinde açık seçilebilirlik, Kotlin ve TypeScript’te geliştiricilerin yaşam kalitesini ciddi biçimde artırdı. Java’da NullAway gibi araçlar var ama zahmetliDil düzeyi desteğin
Optional/Maybeden çok daha iyi olduğunu düşünüyorum. Çünkü kodumap/flatMaprayına oturtmak yerine gerçek mantığa odaklanmayı sağlıyorhttps://github.com/uber/NullAway
Sadece başka bir JVM dili kullanılsa olmaz mı
Site şu anda kapalı olduğu için arşiv bağlantısını bırakıyorum: https://web.archive.org/web/20240802081039/https://bugs.open...
“Programın oluşabilecek tüm
nulldeğerleri açıkça işlemesini zorunlu kılmak hedef değil; işlenmemişnulldeğerleri derleme sırasında uyarı olabilir ama hata değildir” demek kötü bir kararJava zaten büyük ölçüde statik tipli bir dil; neden bir dinamik davranış daha ekleniyor anlamıyorum. Umarım bu uyarıları hataya yükseltmenin kolay bir yolu olur
nulldönüşleri işleyecek şekilde yeniden yazılması gerekir. Bu ek özellikle zorunlunullişleme yalnızca yeni tiplerle ilgili işlemlere uygulanabiliyor; bu yüzden hiçbir şey bozulmuyorHer durumda
null/nilişlemeyi tip sisteminin zorunlu kıldığı diller elbette çok daha iyi. Ama mevcut Java böyle bir dil değil. Yine de bu büyük bir iyileştirme olacakBu dersleri çok geç öğreniyor olmamız üzücü. Varsayılan olarak non-nullable, varsayılan olarak immutable, varsayılan olarak en dar kapsam olmalı
Yeni tasarımlarda “güvenli yola düşürmek” yerine fazlasıyla sık şekilde anlık kullanım kolaylığı tercih ediliyor. Güvenli varsayılanlar çok daha özenli tasarım ve kullanıcı deneyimi gerektirir; ama sonuçta neredeyse her dilde, platformda ve teknolojide bir sürü ayağa sıkma tuzağı oluşuyor. İnşaat ve elektrik mühendisliğinde yönetmelikler var; yazılım ise yaklaşık her 30 yılda bir yeni dil ve teknolojilerde aynı dersleri yeniden öğreniyor
Java, mikropları öldürmek için suyu kaynatmak gerektiğini öğrenen üçüncü dünya köyü gibi
Facebook’ta yaptığım işlerin çoğu Hack kullanmaktı. Null olup olmama durumu Hack tip sisteminin temel bir unsuru ve gerçekten çok sayıda gereksiz hatayı çözüyor
Elbette bu, beklenmedik bir
nulldeğerini hiç alamayacağınız anlamına gelmiyor. Bu özellik de dile sonradan eklendiği için PHP köklerini yansıtan legacymixedtipi hâlâ çok fazlaydı; bu da fiilen her şey olabilir demektiÖnce nullable dizilerin ne olacağını merak ediyorum.
String![]örneği nesneninnullolabildiği durumu gösteriyor ama dizinin kendisi ne olacak? Java’daString labels[] = null;tamamen geçerli. O zamanString![]! labels;gibi mi bildirmek gerekir?Hack’te
vec $foo, hemfoo’nun hem de elemanlarınnullolmadığı anlamına gelir;?vec $fooise elemanların non-null amafoo’nun nullable olduğu anlamına gelir. Pratiktenulldizi kullanmak için neredeyse hiç neden yok, bu yüzden varsayılannullolamaz olmalı. Ancak Java’da tüm legacy kodun null olasılığını varsayması gibi bir sorun varÖnerideki
Object! o1 = s,Object o2 = id(s),Object o3 = (String!) sörneklerinde 2 ve 3’ün derleme hatası olması gerekmez mi diye düşünüyorumSon olarak Java’nın cast’inden çok Hack’in
aszorlama operatörünü seviyorum. Örneğinfoo($b)derleme hatası verir;$b as A, değernullise runtime hatası verir;$a as ?Bise B ise cast eder, değilsenulldöndürürSonuçta soru, bunun Java SDK üzerine uygulanıp uygulanamayacağı ve legacy kodda nasıl görüneceği oluyor
https://docs.hhvm.com/hack/types/nullable-types
String![]? labels = null;olurKotlin’in iyi yanları artık Java’ya da giriyor gibi
Yine de Lombok gibi şeylerle uğraşmak zorunda kalmadığım Kotlin’de çalışmaya devam etmek isterim. Java record’ları güzel gerçi