Optional
Java'ya eklenmesinin nedeni şudur:
return Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
.stream()
.filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
.filter(m -> Arrays.equals(m.getParameterTypes(), parameterClasses))
.filter(m -> Objects.equals(m.getReturnType(), returnType))
.findFirst()
.getOrThrow(() -> new InternalError(...));
bundan daha temiz:
Method matching =
Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
.stream()
.filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
.filter(m -> Arrays.equals(m.getParameterTypes(), parameterClasses))
.filter(m -> Objects.equals(m.getReturnType(), returnType))
.getFirst();
if (matching == null)
throw new InternalError("Enclosing method not found");
return matching;
Demek istediğim, isteğe bağlı olarak Java'ya aynı anda eklenen işlevsel programlamayı desteklemek için yazılmıştır . (Örnek , Brian Goetz tarafından bir blogun izniyle gelir . orElse()
Bu kod zaten bir istisna atacağı için daha iyi bir örnek yöntemi kullanabilir , ancak resmi elde edersiniz.)
Ama şimdi, insanlar isteğe bağlı olarak çok farklı bir nedenle kullanıyorlar. Bunu dil tasarımındaki bir kusuru gidermek için kullanıyorlar. Kusur şudur: Bir API'nin parametrelerinin ve dönüş değerlerinden hangisinin boş olmasına izin verileceğini belirtmenin bir yolu yoktur. Javadoclarda bahsedilebilir, ancak çoğu geliştirici kodları için javadoc bile yazmaz ve pek çoğu javadocları yazarken kontrol etmez. Bu nedenle, çağrı yığınının dokuz veya on katı kadar defalarca onaylanmış olmalarına rağmen, genellikle boş olamazlarsa da, bunları kullanmadan önce her zaman null değerleri kontrol eden birçok koda yol açar.
Bence bu kusuru çözmek için gerçek bir susuzluk var, çünkü yeni İsteğe bağlı sınıfı gören birçok kişi amacının API'lara netlik katmak olduğunu varsayıyordu. Bu yüzden insanlar "alıcılar Opsiyonelleri iade etmeli mi?" Hayır, alıcının işlevsel programlamada kullanılmasını beklemediğiniz sürece, muhtemelen mümkün olmamalıdır. Aslında, İsteğe Bağlı Java API'sinin nerede kullanıldığına bakarsanız, temel olarak fonksiyonel programlamanın çekirdeği olan Stream sınıflarında bulunur. (Çok ayrıntılı bir şekilde kontrol etmedim, ancak Stream sınıfları kullandıkları tek yer olabilir .)
Bir alıcı kodunu fonksiyonel kodda kullanmayı planlıyorsanız, standart bir alıcıya ve İsteğe bağlı olarak dönen ikinci bir alıcıya sahip olmak iyi bir fikir olabilir.
Oh, ve sınıfınızın serileştirilebilir olması gerekiyorsa, kesinlikle İsteğe bağlı kullanmamalısınız.
Opsiyoneller API kusuruna karşı çok kötü bir çözümdür çünkü a) çok ayrıntılıdırlar ve b) Bu problemi asla en başta çözmeyi amaçlamamışlardır.
API kusuruna çok daha iyi bir çözüm Nullness Checker'dır . Bu, @Nullable ile açıklama ekleyerek hangi parametrelerin ve dönüş değerlerinin boş olmasına izin verileceğini belirlemenizi sağlayan bir ek açıklama işlemcisidir. Bu şekilde, derleyici kodu tarayabilir ve aslında null olabilecek bir değerin null değerine izin verilmeyen bir değere geçirilip geçirilmediğini anlayabilir. Varsayılan olarak, açıklama eklenmedikçe hiçbir şeyin boş kalmasına izin verilmediğini varsayar. Bu şekilde, null değerler konusunda endişelenmenize gerek kalmaz. Bir parametreye null değer iletilmesi derleyici hatasına neden olur. Bir nesneyi null olamaz olarak null için sınamak derleyici uyarısı oluşturur. Bunun etkisi, NullPointerException'ı bir çalışma zamanı hatasından derleme zamanı hatasına dönüştürmektir.
Bu her şeyi değiştirir.
Alıcılarınıza gelince, İsteğe Bağlı'yı kullanmayın. Ve sınıflarınızı tasarlamaya çalışın, böylece üyelerin hiçbiri boş olamaz. Ve belki de Nullness Checker'ı projenize eklemeyi ve ihtiyaç duymaları durumunda geters ve setter parametrelerinizi @Nullable olarak bildirmeyi deneyin. Bunu sadece yeni projelerle yaptım. Muhtemelen null için çok sayıda gereksiz testle yazılmış mevcut projelerde çok fazla uyarı üretiyor, bu nedenle güçlendirilmesi zor olabilir. Ama aynı zamanda birçok hata yakalayacak. Onu seviyorum. Kodum bu yüzden çok daha temiz ve daha güvenilir.
(Buna hitap eden yeni bir dil de var. Java bayt kodunu derleyen Kotlin, bir nesnenin bildirdiğinizde boş olup olmayacağını belirlemenizi sağlar. Daha temiz bir yaklaşımdır.)
Orijinal Gönderi Eki (sürüm 2)
Bir sürü düşünce verdikten sonra, isteksizce geri dönmenin kabul edilebilir olduğu sonucuna vartım Bir koşulda isteğe bağlı: Alınan değerin aslında boş olabileceği. Ben insanlar rutin olarak döndürmek kodu bir sürü gördüm İsteğe bağlı muhtemelen null döndüremez alıcılar. Bu sadece hata daha olası kılan, kod karmaşıklığı ekleyen çok kötü bir kodlama uygulaması olarak görüyorum. Ancak, döndürülen değer gerçekten boş olabiliyorsa, devam edin ve bir İsteğe Bağlı içine sarın.
İşlevsel programlama için tasarlanan ve işlev başvurusu gerektiren yöntemlerin, biri İsteğe Bağlı kullanan iki biçimde yazılacağını (ve yapılması gerektiğini) unutmayın. Örneğin Optional.map()
ve Optional.flatMap()
her ikisi de işlev referanslarını alır. Birincisi sıradan bir alıcıya bir referans alır ve ikincisi İsteğe bağlı olanı alır. Yani değerin boş olamayacağı bir İsteğe bağlı döndürerek kimseye bir iyilik yapmazsınız.
Tüm bunları söyledikten sonra, NullPointerExceptions zaman hatalarını derlemek için çalışma zamanı hatalarından çevirdikleri için Nullness Checker tarafından kullanılan yaklaşımın null'larla başa çıkmanın en iyi yolu olduğunu görüyorum .