Avoiding! = Null deyimleri


Al─▒nan cevaba git


Kulland─▒─č─▒m object != null ├Ânlemek i├žin ├žok NullPointerException .

Buna iyi bir alternatif var m─▒?

├ľrne─čin:

 if (someobject != null) {
    someobject.doCalc();
}
 

Bu NullPointerException , nesne olup olmad─▒─č─▒n─▒n bilinmedi─či durumlarda a'y─▒ ├Ânler null .

Kabul edilen cevab─▒n g├╝ncel olmad─▒─č─▒n─▒ unutmay─▒n, daha yeni bir yakla┼č─▒m i├žin https://stackoverflow.com/a/2386013/12943 adresine bak─▒n .


3881









Cevap say─▒s─▒n─▒ say: 30






Bu bana g├Âre, orta ila orta seviyedeki geli┼čtiricilerin bir noktada kar┼č─▒ kar┼č─▒ya gelme e─čiliminde oldu─ču olduk├ža yayg─▒n bir sorun gibi g├Âr├╝n├╝yor: Kat─▒lmakta olduklar─▒ s├Âzle┼čmeleri bilmezler veya g├╝venmezler ve nulllar i├žin savunmalar─▒n─▒ ├╝stlenirler. Ek olarak, kendi kodlar─▒n─▒ yazarken, arayan─▒n bo┼č de─čerleri kontrol etmesini gerektiren bir ┼čeyi belirtmek i├žin bo┼č de─čerlere geri d├Ânmeye g├╝venirler.

Ba┼čka bir deyi┼čle, null denetiminin ortaya ├ž─▒kt─▒─č─▒ iki ├Ârnek vard─▒r:

  1. Null s├Âzle┼čme bak─▒m─▒ndan ge├žerli bir cevap ise; ve

  2. Ge├žerli bir cevap olmad─▒─č─▒ durumlarda.

(2) kolayd─▒r. assert ─░fadeleri kullan─▒n (iddialar) veya hataya izin verin (├Ârne─čin, NullPointerException ). ─░ddialar, 1.4'te eklenmi┼č olduk├ža az kullan─▒lan bir Java ├Âzelli─čidir. S├Âzdizimi:

 assert <condition>
 

veya

 assert <condition> : <object>
 

burada <condition> bir boole ifadesidir ve y├Ânteminin ├ž─▒kt─▒s─▒ hataya dahil edilecek <object> bir nesnedir toString() .

Ko┼čul do─čru de─čilse, bir assert ifade Error ( AssertionError ) atar . Varsay─▒lan olarak, Java iddialar─▒ dikkate almaz. Se├žene─či JVM'ye ileterek iddialar─▒ etkinle┼čtirebilirsiniz -ea . Bireysel s─▒n─▒flar ve paketler i├žin iddialar─▒ etkinle┼čtirebilir ve devre d─▒┼č─▒ b─▒rakabilirsiniz. Bu, testlerimin iddialarda performans etkisi olmad─▒─č─▒n─▒ g├Âstermi┼č olmas─▒na ra─čmen, geli┼čtirirken ve test ederken kodu onaylayabilir ve bunlar─▒ ├╝retim ortam─▒nda devre d─▒┼č─▒ b─▒rakabilirsiniz.

Bu durumda iddialar─▒ kullanmamak tamamd─▒r, ├ž├╝nk├╝ kod sadece ba┼čar─▒s─▒z olur; bu, iddialar─▒ kullan─▒rsan─▒z ne olaca─č─▒d─▒r. Tek fark, iddialarla daha erken, daha anlaml─▒ bir ┼čekilde ve muhtemelen de beklemiyorsan─▒z neden oldu─čunu anlaman─▒za yard─▒mc─▒ olabilecek ilave bilgilerle ger├žekle┼čmesidir.

(1) biraz daha zor. Arad─▒─č─▒n─▒z kod ├╝zerinde kontrol sahibi de─čilseniz, o zaman s─▒k─▒┼čm─▒┼čs─▒n─▒z demektir. E─čer null ge├žerli bir cevap ise, kontrol etmeniz gerekir.

Ancak, kontrol etti─činiz kod ise (ve bu genellikle durum b├Âyledir), o zaman farkl─▒ bir hikaye. Yan─▒t olarak bo┼č de─čer kullanmaktan ka├ž─▒n─▒n. Koleksiyonlar─▒ d├Ând├╝ren y├Ântemlerle, kolay: hemen hemen bo┼č sat─▒rlar yerine bo┼č koleksiyonlar (veya diziler) d├Ând├╝r├╝n.

Tahsilats─▒z ├╝r├╝nlerde daha zor olabilir. Bunu bir ├Ârnek olarak d├╝┼č├╝n├╝n: e─čer bu aray├╝zlere sahipseniz:

 public interface Action {
  void doSomething();
}

public interface Parser {
  Action findAction(String userInput);
}
 

Parser, ham kullan─▒c─▒ girdisini al─▒r ve yap─▒lacak bir ┼čey bulur, belki de bir ┼čey i├žin komut sat─▒r─▒ aray├╝z├╝ uyguluyorsan─▒z. ┼×imdi, uygun bir i┼člem yap─▒lmad─▒─č─▒ takdirde iade edece─činiz s├Âzle┼čmeyi iptal edebilirsiniz. Bu, hakk─▒nda konu┼čtu─čunuz bo┼č kontrol yol a├žar.

Alternatif bir ├ž├Âz├╝m asla bo┼ča d├Ânmemek ve bunun yerine Bo┼č Nesne desenini kullanmakt─▒r :

 public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }
}
 

Kar┼č─▒la┼čt─▒rmak:

 Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing
} else {
  action.doSomething();
}
 

i├žin

 ParserFactory.getParser().findAction(someInput).doSomething();
 

bu ├žok daha iyi bir tasar─▒m ├ž├╝nk├╝ daha ├Âzl├╝ kodlara yol a├ž─▒yor.

Bu, belki de FindAction () y├Ânteminin anlaml─▒ bir hata mesaj─▒ i├žeren bir ─░stisna atmas─▒ i├žin tamamen uygundur - ├Âzellikle bu durumda kullan─▒c─▒ girdisine g├╝veniyorsunuz. FindAction y├Ânteminin bir ─░stisna atmas─▒, ├ža─č─▒ran y├Ântemin a├ž─▒klama yapmadan basit bir NullPointerException ile havaya u├žurulmas─▒ndan ├žok daha iyi olurdu.

 try {
    ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());
}
 

─░sterseniz, deneyin / yakala mekanizmas─▒n─▒n ├žok ├žirkin oldu─čunu d├╝┼č├╝n├╝yorsan─▒z, Hi├žbir ┼×ey yapmak yerine varsay─▒lan i┼čleminizin kullan─▒c─▒ya geri bildirim sa─člamas─▒ gerekir.

 public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething() {
            userConsole.err("Action not found: " + userInput);
        }
    }
}
 

2570







JetBrains IntelliJ IDEA , Eclipse veya Netbeans gibi bir Java IDE veya findbugs gibi bir ara├ž kullan─▒yorsan─▒z (veya kullanmay─▒ planl─▒yorsan─▒z) , bu sorunu ├ž├Âzmek i├žin ek a├ž─▒klamalar kullanabilirsiniz.

Temelde, @Nullable ve var @NotNull .

Bunun gibi y├Ântem ve parametrelerde kullanabilirsiniz:

 @NotNull public static String helloWorld() {
    return "Hello World";
}
 

veya

 @Nullable public static String helloWorld() {
    return "Hello World";
}
 

─░kinci ├Ârnek derlenmeyecek (IntelliJ IDEA'da).

─░lk helloWorld() i┼člevi ba┼čka bir kod par├žas─▒nda kulland─▒─č─▒n─▒zda:

 public static void main(String[] args)
{
    String result = helloWorld();
    if(result != null) {
        System.out.println(result);
    }
}
 

┼×imdi IntelliJ IDEA derleyicisi, helloWorld() fonksiyonun hi├žbir zaman geri d├Ânmeyece─činden ├žekin i┼če yaramaz oldu─čunu size s├Âyleyecektir null .

Parametre kullanarak

 void someMethod(@NotNull someParameter) { }
 

e─čer b├Âyle bir ┼čey yazarsan─▒z:

 someMethod(null);
 

Bu derlenmeyecek.

Son ├Ârnek kullan─▒m─▒ @Nullable

 @Nullable iWantToDestroyEverything() { return null; }
 

Bunu yap─▒yor

 iWantToDestroyEverything().something();
 

Ve bunun olmayaca─č─▒ndan emin olabilirsin. :)

Derleyicinin genellikle oldu─čundan daha fazlas─▒n─▒ kontrol etmesine izin vermek ve s├Âzle┼čmelerinizi daha g├╝├žl├╝ olmaya zorlamak i├žin iyi bir yol. Ne yaz─▒k ki, t├╝m derleyiciler taraf─▒ndan desteklenmiyor.

IntelliJ IDEA 10.5 ve sonras─▒nda, di─čer @Nullable @NotNull uygulamalar i├žin destek eklediler .

Blog g├Ânderisine bak─▒n Daha esnek ve yap─▒land─▒r─▒labilir @ Nullable / @ NotNull ek a├ž─▒klamalar─▒ .


596







Bo┼č de─čerlere izin verilmiyorsa

E─čer y├Ânteminiz harici olarak adland─▒r─▒l─▒yorsa, ┼čunun gibi bir ┼čeyle ba┼člay─▒n:

 public void method(Object object) {
  if (object == null) {
    throw new IllegalArgumentException("...");
  }
 

Ard─▒ndan, bu y├Ântemin geri kalan─▒nda object bunun bo┼č olmad─▒─č─▒n─▒ bilirsiniz .

Dahili bir y├Ântemse (bir API'nin par├žas─▒ de─čil), sadece null olamayaca─č─▒n─▒ belgeleyin, o kadar.

├ľrnek:

 public String getFirst3Chars(String text) {
  return text.subString(0, 3);
}
 

Bununla birlikte, e─čer y├Ânteminiz sadece de─čeri ge├žerse ve bir sonraki y├Ântem onu ÔÇőÔÇőge├žerse vb. Sorunlu olabilir. Bu durumda, arg├╝man─▒ yukar─▒daki gibi kontrol etmek isteyebilirsiniz.

Null izin verilirse

Bu ger├žekten ba─čl─▒d─▒r. E─čer s─▒k ÔÇőÔÇős─▒k b├Âyle bir ┼čey yapt─▒─č─▒m─▒ anlarsan─▒z:

 if (object == null) {
  // something
} else {
  // something else
}
 

Bu y├╝zden dall─▒yorum ve iki tamamen farkl─▒ ┼čeyler yap─▒yorum. ├çirkin kod pasaj─▒ yok ├ž├╝nk├╝ verilere ba─čl─▒ olarak iki farkl─▒ ┼čey yapmam gerekiyor. ├ľrne─čin, girdi ├╝zerinde ├žal─▒┼čmal─▒ m─▒y─▒m, yoksa iyi bir varsay─▒lan de─čer mi hesaplamal─▒y─▒m?


" if (object != null && ... " Deyimini kullanmam ├žok nadiren ger├žekle┼čti .

Genelde deyimi kulland─▒─č─▒n─▒z yerlere ├Ârnekler verirseniz, size ├Ârnekler vermek daha kolay olabilir.


304







Vay be, ├Ânermek i├žin 57 farkl─▒ y├Ântemimiz varken neredeyse ba┼čka bir cevap eklemekten nefret ediyorum NullObject pattern , ancak bu soruya ilgi duyan baz─▒ ki┼čilerin Java 7 i├žin "null-g├╝venli" eklemek i├žin bir ├Âneri oldu─čunu bilmek isteyebilece─čini d├╝┼č├╝n├╝yorum ba┼ča ├ž─▒kma " ÔÇöa-e┼čit olmayan-bo┼č mant─▒k i├žin aerodinamik s├Âzdizimi.

Alex Miller taraf─▒ndan verilen ├Ârnek ┼č├Âyle g├Âr├╝n├╝r:

 public String getPostcode(Person person) {  
  return person?.getAddress()?.getPostcode();  
}  
 

Bu ?. ara├ž sadece bo┼č de─čilse sol tan─▒mlay─▒c─▒y─▒ referanstan ├ž─▒kar─▒r, aksi takdirde ifadenin kalan─▒n─▒ ┼ču ┼čekilde de─čerlendirir null . Java Posse ├╝yesi Dick Wall ve Devoxx'teki se├žmenler gibi baz─▒ insanlar bu ├Âneriyi ger├žekten seviyorlar, ancak asl─▒nda null bir sentinel de─čeri olarak daha fazla kullan─▒m─▒n─▒ te┼čvik edece─či gerek├žesiyle de muhalefet var .


G├╝ncelleme: Bir resmi ├Âneri Java 7'de bo┼č g├╝venlikli operat├Âr├╝ i├žin alt─▒nda sunulmu┼čtur Proje Coin. S├Âzdizimi yukar─▒daki ├Ârnekten biraz farkl─▒, ancak ayn─▒ fikir.


G├╝ncelleme: Bo┼č g├╝venli operat├Âr teklifi, Project Coin i├žine girmedi. Yani bu s├Âzdizimini Java 7'de g├Ârmeyeceksiniz.


230







Tan─▒mlanmam─▒┼č de─čerlere izin verilmiyorsa:

IDE'nizi, potansiyel s─▒f─▒r ba┼čvurular─▒ konusunda sizi uyaracak ┼čekilde yap─▒land─▒rabilirsiniz. ├ľrne─čin Eclipse'de, Tercihler> Java> Derleyici> Hatalar / Uyar─▒lar / Bo┼č Analiz b├Âl├╝m├╝ne bak─▒n─▒z .

Tan─▒mlanmam─▒┼č de─čerlere izin verilirse:

Tan─▒mlanmam─▒┼č de─čerlerin anlaml─▒ oldu─ču yeni bir API tan─▒mlamak istiyorsan─▒z , Se├ženek ├ľr├╝nt├╝s├╝n├╝ kullan─▒n (i┼člevsel dillerden a┼čina olabilir). A┼ča─č─▒daki avantajlara sahiptir:

  • API'de bir girdi veya ├ž─▒k─▒┼č─▒n olup olmad─▒─č─▒ a├ž─▒k├ža belirtilir.
  • Derleyici sizi "tan─▒ms─▒z" durumla ilgilenmeye zorlar.
  • Se├ženek bir monad't─▒r , bu nedenle ayr─▒nt─▒l─▒ bo┼č denetlemeye gerek yoktur, de─čeri g├╝venle kullanmak i├žin map / foreach / getOrElse veya benzer bir birle┼čtiriciyi kullan─▒n (├Ârnek) .

Java 8 yerle┼čik bir Optional s─▒n─▒fa sahiptir (├Ânerilir); ├Ânceki s├╝r├╝mleri i├žin, k├╝t├╝phane alternatifler vard─▒r ├Ârne─čin Guava 'n─▒n Optional veya FunctionalJava ' ─▒n Option . Ancak bir├žok i┼člevsel stilde oldu─ču gibi, Java'da Option (8 bile olsa) kullanmak, daha az ayr─▒nt─▒l─▒ bir JVM dili, ├Ârne─čin Scala veya Xtend kullanarak azaltabilece─činiz olduk├ža fazla bir boylerle sonu├žlan─▒r.

Bo┼č de─čer d├Ând├╝ren bir API ile u─čra┼čmak zorundaysan─▒z , Java'da fazla bir ┼čey yapamazs─▒n─▒z. Xtend ve Groovy, Elvis operat├Âr├╝ne ?: ve s─▒f─▒r g├╝venlikli dereference operat├Âr├╝ne sahiptir ?. , ancak bo┼č bir referans olmas─▒ durumunda bo┼č de─čerin geri d├Ând├╝─č├╝n├╝ unutmay─▒n, bu nedenle bo┼č de─čerin do─čru i┼členmesini "savunur".


190







Sadece bu durum i├žin -

Bir e┼čittir y├Ântemini ├ža─č─▒rmadan ├Ânce bir de─či┼čkenin null olup olmad─▒─č─▒n─▒ kontrol etmemek (a┼ča─č─▒da bir dize kar┼č─▒la┼čt─▒rma ├Ârne─či):

 if ( foo.equals("bar") ) {
 // ...
}
 

Bir neden olacakt─▒r NullPointerException e─čer foo yok.

S'nizi b├Âyle kar┼č─▒la┼čt─▒r─▒rsan─▒z bundan ka├ž─▒nabilirsiniz String :

 if ( "bar".equals(foo) ) {
 // ...
}
 

176







Java 8 ile java.util.Optional tart─▒┼č─▒lan sorunun bir k─▒sm─▒n─▒ ├ž├Âzen yeni bir s─▒n─▒f geliyor . En az─▒ndan, kodun okunabilirli─čini artt─▒rd─▒─č─▒n─▒ ve genel API'ler s├Âz konusu oldu─čunda API s├Âzle┼čmesini m├╝┼čteri geli┼čtiricisine daha a├ž─▒k hale getirdi─čini s├Âyleyebiliriz.

B├Âyle ├žal─▒┼č─▒rlar:

Belirli bir t├╝r ( Fruit ) i├žin iste─če ba─čl─▒ bir nesne, y├Ântemin d├Ân├╝┼č t├╝r├╝ olarak olu┼čturulur. Bo┼č olabilir veya bir Fruit nesne i├žerebilir :

 public static Optional<Fruit> find(String name, List<Fruit> fruits) {
   for (Fruit fruit : fruits) {
      if (fruit.getName().equals(name)) {
         return Optional.of(fruit);
      }
   }
   return Optional.empty();
}
 

┼×imdi, belirli bir Fruit ├Ârne─či i├žin Fruit ( fruits ) listesinde bir arama yapt─▒─č─▒m─▒z ┼ču koda bak─▒n :

 Optional<Fruit> found = find("lemon", fruits);
if (found.isPresent()) {
   Fruit fruit = found.get();
   String name = fruit.getName();
}
 

map() ─░ste─če ba─čl─▒ bir nesnede bir hesaplama yapmak - veya bir de─čerden de─čer almak i├žin i┼čleci kullanabilirsiniz . orElse() Eksik de─čerler i├žin geri d├Ân├╝┼č sa─člar.

 String nameOrNull = find("lemon", fruits)
    .map(f -> f.getName())
    .orElse("empty-name");
 

Tabii ki, bo┼č / bo┼č de─čer kontrol├╝ hala gereklidir, ancak en az─▒ndan geli┼čtirici de─čerin bo┼č olabilece─činin ve kontrol etmeyi unutman─▒n riskinin s─▒n─▒rl─▒ oldu─čunun bilincindedir.

Ne Optional zaman bir d├Ân├╝┼č de─čeri bo┼č olsa bile s─▒f─▒rdan in┼ča edilen bir API'de ve yaln─▒zca null (kural olmadan) d├╝z bir nesneyi d├Ând├╝r├╝rken , istemci kodu basit nesne d├Ân├╝┼č de─čerleri ├╝zerindeki bo┼č kontrolleri b─▒rakabilir ...

Elbette Optional , bir y├Ântem arg├╝man─▒ olarak da kullan─▒labilir, belki de baz─▒ durumlarda iste─če ba─čl─▒ arg├╝manlar─▒ belirtmek i├žin 5 veya 10 a┼č─▒r─▒ y├╝kleme y├Ânteminden daha iyi bir y├Ântem olabilir.

Optional orElse Varsay─▒lan bir de─čerin kullan─▒lmas─▒na izin veren ve lambda ifadeleriyle ifPresent ├žal─▒┼čan di─čer uygun y├Ântemleri sunar .https://en.wikipedia.org/wiki/Anonymous_function

Sizi, NullPointerException (ve genel olarak bo┼č g├Âsterici) sorunlu oldu─ču kadar (k─▒smi) ├ž├Âz├╝m├╝n Optional iyi a├ž─▒kland─▒─č─▒: ( Opsiyonel Nesneler ) sorunlu olan bu makaleyi (bu cevab─▒ yazmak i├žin benim ana kayna─č─▒m) okumaya davet ediyorum .


160







Hangi t├╝r nesneleri kontrol etti─činize ba─čl─▒ olarak, apache commons'daki baz─▒ s─▒n─▒flar─▒ kullanabilirsiniz: apache commons lang ve apache commons koleksiyonlar─▒

├ľrnek:

 String foo;
...
if( StringUtils.isBlank( foo ) ) {
   ///do something
}
 

veya (neyi kontrol etmeniz gerekti─čine ba─čl─▒ olarak):

 String foo;
...
if( StringUtils.isEmpty( foo ) ) {
   ///do something
}
 

StringUtils s─▒n─▒f─▒ bir├žo─čundan sadece biridir; Commons'da g├╝venli manip├╝lasyon yapmayan birka├ž iyi s─▒n─▒f var.

Burada, apache k├╝t├╝phanesini (commons-lang-2.4.jar) eklerken JAVA'da null ge├žerlili─či nas─▒l kullanabilece─činizi g├Âsteren bir ├Ârnek izler.

 public DOCUMENT read(String xml, ValidationEventHandler validationEventHandler) {
    Validate.notNull(validationEventHandler,"ValidationHandler not Injected");
    return read(new StringReader(xml), true, validationEventHandler);
}
 

E─čer Spring kullan─▒yorsan─▒z, Spring ayr─▒ca paketinde de ayn─▒ i┼člevselli─če sahiptir, k├╝t├╝phaneye bak─▒n─▒z (spring-2.4.6.jar)

Bu statik classf'─▒n bahardan nas─▒l kullan─▒laca─č─▒na dair ├Ârnek (org.springframework.util.Assert)

 Assert.notNull(validationEventHandler,"ValidationHandler not Injected");
 

122







  • Bir nesnenin bo┼č olmamas─▒ gerekti─čini d├╝┼č├╝n├╝yorsan─▒z (veya bir hata ise) bir assert kullan─▒n.
  • Metodunuz bo┼č params kabul etmezse, javadoc i├žinde s├Âyleyin ve bir assert kullan─▒n.

Nesne denetlemeniz gerekir! = Null sadece nesnenin bo┼č olabilece─či durumla ilgilenmek istiyorsan─▒z ...

Java7'ye bo┼č / kay─▒ts─▒z params ile yard─▒mc─▒ olmak i├žin yeni ek a├ž─▒klamalar ekleme ├Ânerisi var: http://tech.puredanger.com/java7/#jsr308


94







"H─▒zl─▒ ba┼čar─▒s─▒z" kodunun hayran─▒y─▒m. Kendinize sorun - parametrenin bo┼č olmas─▒ durumunda faydal─▒ bir ┼čey mi yap─▒yorsunuz? E─čer kodunuzun bu durumda ne yapmas─▒ gerekti─čine dair net bir cevab─▒n─▒z yoksa ... yani ilk etapta asla bo┼č b─▒rak─▒lmamal─▒, sonra ihmal edilmeli ve NullPointerException'─▒n at─▒lmas─▒na izin verilmelidir. ├ça─č─▒ran kod, bir NPE'yi bir IllegalArgumentException'─▒n yapaca─č─▒ kadar anlaml─▒ hale getirecektir, ancak geli┼čtiricinin bir NPE at─▒l─▒rsa, kodunuz beklenmedik bir ba┼čka bir durum y├╝r├╝tmeye ├žal─▒┼čmak yerine neyin yanl─▒┼č gitti─čini anlamak ve hata ay─▒klamak daha kolay olacakt─▒r. mant─▒k - sonu├žta uygulaman─▒n yine de ba┼čar─▒s─▒z olmas─▒na neden olur.


89







Google koleksiyonlar─▒ ├žer├ževesi, s─▒f─▒r kontrol├╝ sa─člamak i├žin iyi ve zarif bir yol sunar.

Bir k├╝t├╝phane s─▒n─▒f─▒nda bunun gibi bir y├Ântem var:

 static <T> T checkNotNull(T e) {
   if (e == null) {
      throw new NullPointerException();
   }
   return e;
}
 

Ve kullan─▒m─▒ (ile import static ):

 ...
void foo(int a, Person p) {
   if (checkNotNull(p).getAge() > a) {
      ...
   }
   else {
      ...
   }
}
...
 

Veya ├Ârne─činizde:

 checkNotNull(someobject).doCalc();
 

75







Bazen, simetrik bir i┼člemi tan─▒mlayan parametreleri ├╝zerinde ├žal─▒┼čan y├Ântemlere sahipsiniz:

 a.f(b); <-> b.f(a);
 

B'nin asla bo┼č olamayaca─č─▒n─▒ biliyorsan, onu de─či┼čtirebilirsin. E┼čitler i├žin en faydal─▒ olan─▒: foo.equals("bar"); Daha iyisini yapmak yerine "bar".equals(foo); .


74







Null Object Pattern yerine - kullan─▒mlar─▒ olan - null nesnesinin bir hata oldu─ču durumlar─▒ d├╝┼č├╝nebilirsiniz.

─░stisna at─▒ld─▒─č─▒nda, y─▒─č─▒n izini inceleyin ve b├Âcek ├╝zerinde ├žal─▒┼č─▒n.


73







Bo┼č bir 'sorun' de─čildir. Tam bir modelleme arac─▒ setinin ayr─▒lmaz bir par├žas─▒d─▒r . Yaz─▒l─▒m, d├╝nyan─▒n karma┼č─▒kl─▒─č─▒n─▒ modellemeyi ama├žlamaktad─▒r ve bo┼č y├╝k├╝n├╝ ta┼č─▒maktad─▒r. Bo┼č , Java ve benzerlerinde 'Veri yok' veya 'Bilinmiyor' ifadesini g├Âsterir . Bu nedenle, bu ama├žlar i├žin bo┼č de─čerlerin kullan─▒lmas─▒ uygundur. 'Bo┼č nesne' modelini tercih etmiyorum; San─▒r─▒m ' koruyucular─▒ kim koruyacak ' sorunu ortaya ├ž─▒kt─▒.
Bana k─▒z arkada┼č─▒m─▒n ad─▒n─▒n ne oldu─čunu sorarsan, sana k─▒z arkada┼č─▒m olmad─▒─č─▒n─▒ s├Âylerim. Java dilinde null d├Ând├╝r├╝r├╝m. Bir alternatif, orada ├ž├Âz├╝lemeyen (veya olmak istemeyen) bir problemi ortaya koymak i├žin anlaml─▒ bir istisna atmak ve kullan─▒c─▒ya veri eri┼čim hatas─▒n─▒ yeniden denemek veya bildirmek i├žin y─▒─č─▒nda daha y├╝ksek bir yere devretmek olabilir.

  1. 'Bilinmeyen bir soru' i├žin 'bilinmeyen cevap' verin. (Bunun i┼čletme a├ž─▒s─▒ndan do─čru oldu─ču yerlerde null de─čerine sahip olun) Kullan─▒mdan ├Ânce bir y├Ântemin i├žinde bir kez null de─čer arg├╝manlar─▒n─▒ kontrol etmek, birden fazla arayan─▒ aramadan ├Ânce kontrol etmekten kurtar─▒r.

     public Photo getPhotoOfThePerson(Person person) {
        if (person == null)
            return null;
        // Grabbing some resources or intensive calculation
        // using person object anyhow.
    }
     

    ├ľnceki, mevcut olmayan bir k─▒z arkada┼č─▒n foto─čraf─▒n─▒ k├╝t├╝phanemden ├žekmemek i├žin normal mant─▒k ak─▒┼č─▒na yol a├žar.

     getPhotoOfThePerson(me.getGirlfriend())
     

    Ve yeni gelen Java API ile uyumludur (d├Ârt g├Âzle bekliyoruz)

     getPhotoByName(me.getGirlfriend()?.getName())
     

    Birileri i├žin DBÔÇÖde depolanan foto─čraf─▒ bulamamak yerine ÔÇťnormal i┼č ak─▒┼č─▒ÔÇŁ olmasa da, di─čer baz─▒ durumlarda a┼ča─č─▒daki gibi ├žiftler kullan─▒rd─▒m

     public static MyEnum parseMyEnum(String value); // throws IllegalArgumentException
    public static MyEnum parseMyEnumOrNull(String value);
     

    Ve <alt> + <shift> + <j> yazmaktan ka├ž─▒n─▒n (Eclipse'de javadoc olu┼čturun) ve size genel API i├žin ├╝├ž ek s├Âzc├╝k yaz─▒n. Bu, dok├╝mantasyonu okumam─▒┼č olanlar hari├ž herkes i├žin fazlas─▒yla yeterli olacakt─▒r.

     /**
     * @return photo or null
     */
     

    veya

     /**
     * @return photo, never null
     */
     
  2. Bu olduk├ža teorik bir durumdur ve ├žo─ču durumda java null g├╝venli API'yi tercih etmelisiniz (10 y─▒l sonra yay─▒nlanacaksa), ancak NullPointerException bir alt s─▒n─▒f─▒d─▒r Exception . Bu nedenle, Throwable makul bir uygulaman─▒n yakalamak isteyebilece─či ko┼čullar─▒ g├Âsteren bir formdur ( javadoc )! ─░stisnalar─▒n ilk avantaj─▒n─▒ kullanmak ve hata i┼čleme kodunu 'normal' koddan ( Java yarat─▒c─▒lar─▒na g├Âre ) ay─▒rmak benim i├žin de benim i├žin uygun NullPointerException .

     public Photo getGirlfriendPhoto() {
        try {
            return appContext.getPhotoDataSource().getPhotoByName(me.getGirlfriend().getName());
        } catch (NullPointerException e) {
            return null;
        }
    }
     

    Sorular ortaya ├ž─▒kabilir:

    S. getPhotoDataSource() Null d├Ând├╝r├╝rse?
    A. ─░┼č mant─▒─č─▒na kalm─▒┼č. Bir foto─čraf alb├╝m├╝ bulamazsam size foto─čraf g├Âsteremem. AppContext ba┼člat─▒lmad─▒ysa ne olur? Bu y├Ântemin i┼č mant─▒─č─▒ buna katlan─▒yor. Ayn─▒ mant─▒k daha kat─▒ olmal─▒ysa, bir istisna atmak i┼č mant─▒─č─▒n─▒n bir par├žas─▒d─▒r ve bo┼č i├žin a├ž─▒k kontrol kullan─▒lmal─▒d─▒r (durum 3). Daha iyi burada yeni bir Java Bo┼č g├╝venli API uyuyor ba┼člat─▒lmas─▒ i├žin se├žici neyi ima ve hangi anlam─▒na gelmez belirtmek i├žin ba┼čar─▒s─▒z h─▒zl─▒ programc─▒ hatalar─▒ durumunda olmak.

    S. Gereksiz kod ├žal─▒┼čt─▒r─▒labilir ve gereksiz kaynaklar tutulabilir.
    C. E─čer getPhotoByName() bir veritaban─▒ ba─člant─▒s─▒ a├žmaya ├žal─▒┼čacaksa PreparedStatement , ki┼či ad─▒n─▒ en sonunda bir SQL parametresi olarak yarat─▒p kullanmaya ba┼člasayd─▒ ger├žekle┼čebilirdi. Bilinmeyen bir soruya yakla┼č─▒m , burada bilinmeyen bir cevap verir (vaka 1). Kaynaklar─▒ yakalamadan ├Ânce, y├Ântem parametreleri kontrol etmeli ve gerekirse 'bilinmeyen' sonucu d├Ând├╝rmelidir.

    S. Bu yakla┼č─▒m, deneme kapatma a├ž─▒l─▒┼č─▒ndan dolay─▒ performans cezas─▒na sahiptir.
    A. Yaz─▒l─▒m─▒n ├Âncelikle anla┼č─▒lmas─▒ ve de─či┼čtirilmesi kolay olmal─▒d─▒r. Ancak bundan sonra, ki┼či performans hakk─▒nda d├╝┼č├╝nebilir ve yaln─▒zca gerekirse! ve gerekti─či yerde! ( kaynak ) ve di─čerleri.

    PS. Bu yakla┼č─▒m, "normal" kod prensibinden ayr─▒ hata i┼čleme kodunun bir yerde kullan─▒lmas─▒ makul oldu─čundan, kullan─▒m─▒ makul olacakt─▒r. Bir sonraki ├Ârne─či ele alal─▒m:

     public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
        try {
            Result1 result1 = performSomeCalculation(predicate);
            Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
            Result3 result3 = performThirdCalculation(result2.getSomeProperty());
            Result4 result4 = performLastCalculation(result3.getSomeProperty());
            return result4.getSomeProperty();
        } catch (NullPointerException e) {
            return null;
        }
    }
    
    public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
        SomeValue result = null;
        if (predicate != null) {
            Result1 result1 = performSomeCalculation(predicate);
            if (result1 != null && result1.getSomeProperty() != null) {
                Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
                if (result2 != null && result2.getSomeProperty() != null) {
                    Result3 result3 = performThirdCalculation(result2.getSomeProperty());
                    if (result3 != null && result3.getSomeProperty() != null) {
                        Result4 result4 = performLastCalculation(result3.getSomeProperty());
                        if (result4 != null) {
                            result = result4.getSomeProperty();
                        }
                    }
                }
            }
        }
        return result;
    }
     

    PPS. H─▒zl─▒ oy kullanmayanlar i├žin (ve d├Âk├╝manlar─▒ okumak i├žin ├žok h─▒zl─▒ de─čiller) hayat─▒mda hi├ž bir zaman bo┼č g├Âsterici istisna (NPE) yakalamad─▒─č─▒m─▒ s├Âylemek isterim. Fakat bu olas─▒l─▒k, Java yarat─▒c─▒lar─▒ taraf─▒ndan kas─▒tl─▒ olarak tasarland─▒ , ├ž├╝nk├╝ NPE bir alt s─▒n─▒f Exception . Java ge├žmi┼činde bir emsal oldu─čundan ThreadDeath , Error asl─▒nda bir uygulama hatas─▒ olmad─▒─č─▒ i├žin de─čil, yaln─▒zca yakalanmas─▒ ama├žlanmad─▒─č─▒ i├žin! Ne kadar NPE bir olmak s─▒─čar Error daha ThreadDeath ! Ama ├Âyle de─čil.

  3. 'Veri yok' se├žene─čini yaln─▒zca i┼č mant─▒─č─▒ ima ederse kontrol edin.

     public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
        if (personId == null)
            return;
        DataSource dataSource = appContext.getStuffDataSource();
        Person person = dataSource.getPersonById(personId);
        if (person != null) {
            person.setPhoneNumber(phoneNumber);
            dataSource.updatePerson(person);
        } else {
            Person = new Person(personId);
            person.setPhoneNumber(phoneNumber);
            dataSource.insertPerson(person);
        }
    }
     

    ve

     public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
        if (personId == null)
            return;
        DataSource dataSource = appContext.getStuffDataSource();
        Person person = dataSource.getPersonById(personId);
        if (person == null)
            throw new SomeReasonableUserException("What are you thinking about ???");
        person.setPhoneNumber(phoneNumber);
        dataSource.updatePerson(person);
    }
     

    AppContext veya dataSource ba┼člat─▒lmam─▒┼čsa, i┼členmemi┼č ├žal─▒┼čma zaman─▒ NullPointerException ge├žerli i┼č par├žac─▒─č─▒n─▒ ├Âld├╝r├╝r ve Thread.defaultUncaughtExceptionHandler taraf─▒ndan i┼členir (en sevdi─činiz g├╝nl├╝─č├╝ veya di─čer bildirim mekanizmas─▒n─▒ tan─▒mlay─▒p kullanman─▒z i├žin). Ayarlanmad─▒ysa, ThreadGroup # uncaughtException , sistem s─▒ras─▒na istif yazd─▒racak. Bir ki┼či uygulama hatas─▒ g├╝nl├╝─č├╝n├╝ izlemeli ve asl─▒nda uygulama hatas─▒ olan i┼členmeyen istisnalar i├žin Jira sorununu a├žmal─▒d─▒r. Programc─▒, ba┼člatma i┼čleminde bir yerde bulunan hatay─▒ d├╝zeltmelidir.


70







Java 7, java.util.Objects ├╝zerinde bir requireNonNull() y├Ântem bulunan yeni bir yard─▒mc─▒ program s─▒n─▒f─▒na sahiptir . B├╝t├╝n bunlar NullPointerException , arg├╝man─▒ null olursa bir atamad─▒r, ancak kodu biraz temizler. ├ľrnek:

 Objects.requireNonNull(someObject);
someObject.doCalc();
 

Bu y├Ântem, her bir kullan─▒mda ├╝├ž sat─▒r kod kaydedebilece─či bir yap─▒c─▒da bir atamadan hemen ├Ânce kontrol etmek i├žin en kullan─▒┼čl─▒d─▒r :

 Parent(Child child) {
   if (child == null) {
      throw new NullPointerException("child");
   }
   this.child = child;
}
 

olur

 Parent(Child child) {
   this.child = Objects.requireNonNull(child, "child");
}
 

69







Sonu├žta, bu sorunu tamamen ├ž├Âzmenin tek yolu farkl─▒ bir programlama dili kullanmakt─▒r:

  • Objective-C'de, bir metodu ├ža─č─▒rmaya e┼čde─čerini yapabilirsiniz nil ve kesinlikle hi├žbir ┼čey olmaz. Bu, bo┼č denetimlerin ├žo─čunu gereksiz k─▒lar, ancak hatalar─▒n te┼čhisi ├žok daha zor hale getirebilir.
  • In Nice'in potansiyel null s├╝r├╝m├╝ ve bo┼č de─čil versiyonu: Bir Java k├Âkenli dil, her t├╝rl├╝ iki s├╝r├╝m├╝ vard─▒r. Yaln─▒zca bo┼č olmayan t├╝rlerde y├Ântemleri ├ža─č─▒rabilirsiniz. Potansiyel olarak null tipler null de─čerinin a├ž─▒k kontrol├╝ ile null olmayan tiplere d├Ân├╝┼čt├╝r├╝lebilir. Bu, bo┼č denetimlerin nerede gerekli oldu─čunu ve nerede olmad─▒klar─▒n─▒ bilmeyi ├žok kolayla┼čt─▒r─▒r.

51







Ger├žekten de Java'da s─▒k kar┼č─▒la┼č─▒lan "sorun".

─░lk olarak, bu konudaki d├╝┼č├╝ncelerim:

NULL ge├žildi─činde, NULL'─▒n ge├žerli bir de─čer olmad─▒─č─▒ bir ┼čeyi "yemenin" k├Ât├╝ oldu─čunu d├╝┼č├╝n├╝yorum. E─čer bir t├╝r hatayla y├Ântemi terk etmiyorsan─▒z, bu y├Ânteminizde do─čru olmayan hi├žbir ┼čeyin yanl─▒┼č olmad─▒─č─▒ anlam─▒na gelir. O zaman muhtemelen bu durumda null de─čerini d├Ând├╝r├╝rs├╝n├╝z ve alma y├Ânteminde yine null de─čerini kontrol edersiniz ve asla bitmez ve "if! = Null", vb. ─░le biter.

Bu nedenle, IMHO, null, daha fazla uygulamay─▒ engelleyen kritik bir hata olmal─▒d─▒r (yani null ge├žerli bir de─čer de─čildir).

Bu sorunu ├ž├Âzme y├Ântemim ┼ču:

─░lk ├Ânce bu s├Âzle┼čmeyi takip ediyorum:

  1. T├╝m genel y├Ântemler / API her zaman null de─čerinin arg├╝manlar─▒n─▒ kontrol eder.
  2. T├╝m ├Âzel y├Ântemler, denetlenen y├Ântem oldu─čundan bo┼č denetlemez (yukar─▒da ele al─▒nmad─▒─č─▒ durumlarda bo┼č nokta istisnas─▒yla ├Âlmesine izin verin)
  3. Null de─čerini denetlemeyen yaln─▒zca di─čer y├Ântemler yard─▒mc─▒ program y├Ântemleridir. Bunlar halka a├ž─▒kt─▒r, ancak bir nedenden ├Ât├╝r├╝ ├ža─č─▒r─▒rsan─▒z, hangi parametreleri ge├žirdi─činizi bilirsiniz. Bu su sa─člamadan su ─▒s─▒t─▒c─▒s─▒ndaki suyu kaynatmaya ├žal─▒┼čmak gibi ...

Ve son olarak, kodda, genel y├Ântemin ilk sat─▒r─▒ ┼č├Âyle devam eder:

 ValidationUtils.getNullValidator().addParam(plans, "plans").addParam(persons, "persons").validate();
 

AddParam () i┼člevinin kendini d├Ând├╝rd├╝─č├╝n├╝ ve denetlemek i├žin daha fazla parametre ekleyebilece─činizi unutmay─▒n.

Parametrelerden biri null olursa y├Ântem validate() i┼čaretli atacakt─▒r ValidationException (i┼čaretli veya i┼čaretli daha fazla tasar─▒m / lezzet sorunu, ancak ValidationException i┼čaretli).

 void validate() throws ValidationException;
 

├ľrne─čin, "planlar" bo┼čsa, mesaj a┼ča─č─▒daki metni i├žerecektir:

" [Plans] parametresi i├žin ge├žersiz arg├╝man de─čeri null de─čeri ile kar┼č─▒la┼č─▒ld─▒ "

G├Ârd├╝─č├╝n├╝z gibi, addParam () y├Ântemindeki (string) ikinci de─čer kullan─▒c─▒ mesaj─▒ i├žin gereklidir, ├ž├╝nk├╝ yans─▒t─▒lan bile de─či┼čken de─či┼čken ad─▒n─▒ (bu yaz─▒ya tabi de─čil) kolayca tespit edemezsiniz.).

Ve evet, bu ├žizginin ├Âtesinde art─▒k bo┼č bir de─čerle kar┼č─▒la┼čmayaca─č─▒m─▒z─▒ biliyoruz, bu y├╝zden bu nesneler ├╝zerinde sadece y├Ântemleri g├╝venle ├ža─č─▒r─▒yoruz.

Bu ┼čekilde, kod temiz, bak─▒m─▒ kolay ve okunabilirdir.


37







Bu soruyu sormak, hata i┼čleme stratejileriyle ilgilenebilece─činize i┼čaret ediyor. Tak─▒m─▒n─▒z─▒n mimar─▒ hatalar─▒n nas─▒l ├žal─▒┼č─▒laca─č─▒na karar vermelidir. Bunu yapman─▒n birka├ž yolu vard─▒r:

  1. ─░stisnalar'─▒n dalgalanmas─▒na izin ver - onlar─▒ 'ana d├Âng├╝de' veya ba┼čka bir y├Ânetim rutinde yakalay─▒n.

    • hata durumlar─▒n─▒ kontrol edin ve bunlar─▒ uygun ┼čekilde ele al─▒n

Tabi ki Y├Ânelimli Programlamaya da g├Âz at─▒n - if( o == null ) handleNull() bayt kodunuza eklemek i├žin d├╝zg├╝n yollar─▒ var .


34







Kullanmaya ek olarak assert a┼ča─č─▒dakileri kullanabilirsiniz:

 if (someobject == null) {
    // Handle null here then move on.
}
 

Bu biraz daha iyidir:

 if (someobject != null) {
    .....
    .....



    .....
}
 

34







Sadece hi├ž bo┼č kullanmay─▒n. ─░zin verme.

S─▒n─▒flar─▒mda, ├žo─ču alan ve yerel de─či┼čken varsay─▒lan de─čerlere sahip de─čildir ve kodun her yerine uyguland─▒─č─▒ndan emin olmak i├žin her yerde s├Âzle┼čme ifadeleri (her zaman a├ž─▒k varsay─▒mlar) eklerim (izin vermekten daha ├Âzl├╝ ve daha anlaml─▒ oldu─čundan NPE olarak gelir ve sonra sat─▒r numaras─▒n─▒, vb. ├ž├Âzmek zorunda kal─▒rs─▒n─▒z).

Bir kez bu uygulamay─▒ benimsedi─čimde, sorunlar─▒n kendili─činden ├ž├Âz├╝lm├╝┼č gibi g├Âr├╝nd├╝─č├╝n├╝ fark ettim. Geli┼čim s├╝recinde daha ├Ânce kaza ile olaylar─▒ yakalar ve zay─▒f bir noktaya sahip oldu─čunuzu fark edersiniz .. ve daha da ├Ânemlisi .. farkl─▒ mod├╝llerin kayg─▒lar─▒n─▒ kapsamaya yard─▒mc─▒ olur, farkl─▒ mod├╝ller birbirlerini 'g├╝venebilir' ve daha fazla ├Ânemsiz b─▒rakmaz. if = null else yap─▒lar─▒ ile kod !

Bu, defansif programlamad─▒r ve uzun vadede daha temiz kodlarla sonu├žlan─▒r. Verileri her zaman sterilize edin, ├Ârne─čin burada kat─▒ standartlar uygulayarak ve problemler ortadan kalkar.

 class C {
    private final MyType mustBeSet;
    public C(MyType mything) {
       mustBeSet=Contract.notNull(mything);
    }
   private String name = "<unknown>";
   public void setName(String s) {
      name = Contract.notNull(s);
   }
}


class Contract {
    public static <T> T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; }
}
 

S├Âzle┼čmeler, ├╝retimde bile her zaman yap─▒lan mini birim testlerine benziyor ve i┼čler ba┼čar─▒s─▒z oldu─čunda, nedense, rastgele bir NPE yerine nedenini ├ž├Âzmeniz gerekti─čini biliyorsunuz.


32







GoogleÔÇÖ─▒n ├žok faydal─▒ bir ├žekirdek k├╝t├╝phanesi olan GuavaÔÇÖda bo┼člu─ču ├Ânlemek i├žin g├╝zel ve faydal─▒ bir API bulunur. UsingAndAvoidingNullExplained program─▒n─▒ ├žok yararl─▒ buluyorum .

Wiki'de a├ž─▒kland─▒─č─▒ gibi:

Optional<T> bo┼č bir T referans─▒n─▒ bo┼č olmayan bir de─čerle de─či┼čtirmenin bir yoludur. ─░ste─če ba─čl─▒, bo┼č olmayan bir T referans─▒ i├žerebilir (bu durumda referans─▒n "mevcut" oldu─čunu s├Âyleyebiliriz) veya hi├žbir ┼čey i├žermeyebilir (bu durumda referans─▒n "yok" oldu─čunu s├Âyleyebiliriz). Asla "bo┼č" i├žerdi─či s├Âylenmez.

Kullan─▒m─▒:

 Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5
 

30







Bu, her Java geli┼čtiricisi i├žin ├žok yayg─▒n bir sorundur. Bu nedenle, Java 8ÔÇÖde, bu kodlar─▒ kar─▒┼č─▒k kod olmadan ele almak i├žin resmi destek var.

Java 8 tan─▒t─▒ld─▒ java.util.Optional<T> . Bo┼č olmayan bir de─čere sahip olan ya da i├žermeyen bir kapt─▒r. Java 8, baz─▒ durumlarda de─čeri bo┼č olabilecek bir nesneyi ele alman─▒n daha g├╝venli bir yolunu sa─člam─▒┼čt─▒r. Haskell ve Scala'n─▒n fikirlerinden ilham alm─▒┼čt─▒r .

├ľzet olarak, ─░ste─če Ba─čl─▒ s─▒n─▒f, bir de─čerin bulundu─ču veya bulunmad─▒─č─▒ durumlarla a├ž─▒k├ža ba┼ča ├ž─▒kma y├Ântemlerini i├žerir. Bununla birlikte, bo┼č referanslara k─▒yasla avantaj─▒, ─░ste─če Ba─čl─▒ <T> s─▒n─▒f─▒n─▒n, de─čerin olmad─▒─č─▒ durum hakk─▒nda sizi d├╝┼č├╝nmeye zorlamas─▒d─▒r. Sonu├ž olarak, istenmeyen bo┼č g├Âsterici istisnalar─▒n─▒ ├Ânleyebilirsiniz.

Yukar─▒daki ├Ârnekte, evde bulunan birden fazla cihaza bir tutama├ž veren bir ev servisi fabrikas─▒ bulunmaktad─▒r. Ancak bu hizmetler mevcut / i┼člevsel olabilir veya olmayabilir; NullPointerException ile sonu├žlanabilece─či anlam─▒na gelir. if Herhangi bir hizmeti kullanmadan ├Ânce bo┼č bir ko┼čul eklemek yerine, ─░ste─če Ba─čl─▒ <Hizmet> se├žene─čine saral─▒m.

SE├çENE─×E DO─×RU <T>

Bir fabrikadan servis referans─▒ almak i├žin bir y├Ântem d├╝┼č├╝nelim. Servis referans─▒n─▒ iade etmek yerine, ─░ste─če Ba─čl─▒ ile kayd─▒r─▒n. API kullan─▒c─▒s─▒n─▒n, iade edilen hizmetin savunmas─▒z kullanabilece─čini veya kullanamayaca─č─▒n─▒ / kullanmayaca─č─▒n─▒ bilmesini sa─člar.

 public Optional<Service> getRefrigertorControl() {
      Service s = new  RefrigeratorService();
       //...
      return Optional.ofNullable(s);
   }
 

G├Ârd├╝─č├╝n├╝z gibi Optional.ofNullable() referans─▒ almak i├žin kolay bir yol sunar. ─░ste─če ba─čl─▒ olarak ba┼čvuru alman─▒n ba┼čka yollar─▒ da vard─▒r Optional.empty() & Optional.of() . Biri null geri d├Ând├╝rmek yerine bo┼č bir nesneyi d├Ând├╝rmek i├žin, di─čeri ise s─▒ras─▒yla geri d├Ând├╝r├╝lemeyen bir nesneyi sarmak i├žin.

ÇOK NULL BİR ÇOK KONTROL KAÇINMAK İÇİN YARDIMCI OLUR?

Bir referans nesnesini tamamlad─▒ktan sonra, Optional, NPE i├žermeyen tamamlanm─▒┼č bir referansta y├Ântemleri ├ža─č─▒rmak i├žin bir├žok yararl─▒ y├Ântem sa─člar.

 Optional ref = homeServices.getRefrigertorControl();
ref.ifPresent(HomeServices::switchItOn);
 

Optional.ifPresent, bo┼č bir de─čer de─čilse, verilen T├╝keticiyi referansla ├ža─č─▒r─▒r. Aksi takdirde, hi├žbir ┼čey yapmaz.

 @FunctionalInterface
public interface Consumer<T>
 

Tek bir giri┼č ba─č─▒ms─▒z de─či┼čkenini kabul eden ve sonu├ž d├Ând├╝rmeyen bir i┼člemi temsil eder. Di─čer bir├žok i┼člevsel arabirimin aksine, T├╝ketici'nin yan etkiler ile ├žal─▒┼čmas─▒ beklenir. ├çok temiz ve anla┼č─▒lmas─▒ kolayd─▒r. Yukar─▒daki kod ├Ârne─činde, HomeService.switchOn(Service) ─░ste─če Ba─čl─▒ tutma referans─▒ bo┼č de─čilse, ├ža─čr─▒l─▒r.

├ť├žl├╝ operat├Âr├╝ bo┼č durumu kontrol etmek i├žin ├žok s─▒k kullan─▒yoruz ve alternatif bir de─čer veya varsay─▒lan de─čer d├Ând├╝r├╝yoruz. ─░ste─če ba─čl─▒, ayn─▒ ko┼čulu null kontrol etmeden ele alman─▒n ba┼čka bir yolunu sunar. Optional.orElse (defaultObj), Optional ├Â─česinin bo┼č de─čeri varsa, defaultObj de─čerini d├Ând├╝r├╝r. Bunu ├Ârnek kodumuzda kullanal─▒m:

 public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}
 

┼×imdi HomeServices.get () ayn─▒ ┼čeyi yapar, ancak daha iyi bir ┼čekilde. Hizmetin zaten ba┼člat─▒lmam─▒┼č olup olmad─▒─č─▒n─▒ kontrol eder. ├ľyleyse, ayn─▒s─▒n─▒ d├Ând├╝r veya yeni bir Yeni servis olu┼čtur. ─░ste─če ba─čl─▒ <T> .orElse (T), varsay─▒lan bir de─čer d├Ând├╝rmeye yard─▒mc─▒ olur.

Son olarak, i┼čte NPE ve null check-free kodu:

 import java.util.Optional;
public class HomeServices {
    private static final int NOW = 0;
    private static Optional<HomeServices> service;

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

public Optional<Service> getRefrigertorControl() {
    Service s = new  RefrigeratorService();
    //...
    return Optional.ofNullable(s);
}

public static void main(String[] args) {
    /* Get Home Services handle */
    Optional<HomeServices> homeServices = HomeServices.get();
    if(homeServices != null) {
        Optional<Service> refrigertorControl = homeServices.get().getRefrigertorControl();
        refrigertorControl.ifPresent(HomeServices::switchItOn);
    }
}

public static void switchItOn(Service s){
         //...
    }
}
 

Yaz─▒n─▒n tamam─▒ NPE ve Null check-free koduÔÇŽ Ger├žekten mi? .


23







Nat Pryce'in makalelerini seviyorum. ─░┼čte linkler:

Makalelerde ayr─▒ca ilgin├ž buldu─čum bir Java Belki T├╝r├╝ i├žin Git deposuna bir ba─člant─▒ var, ancak tek ba┼č─▒na kontrol kodu ┼či┼čirmesini azaltabilece─čini sanm─▒yorum. ─░nternette biraz ara┼čt─▒rma yapt─▒ktan sonra, bence ! = Null kod ┼či┼čmesi, ├Âzellikle dikkatli bir tasar─▒mla azalt─▒labilir.


22







Ben denedim NullObjectPattern ama benim i├žin her zaman gitmek i├žin en iyi yol de─čildir. Bazen bir "eylem yok" uygun de─čilken vard─▒r.

NullPointerException geli┼čtiricilerin hatas─▒ oldu─ču ve yeterince deneyimle hatalar─▒n tam olarak nerede oldu─čunu size s├Âyleyen bir ├çal─▒┼čma Zaman─▒ istisnas─▒d─▒r .

┼×imdi cevaba:

T├╝m niteliklerinizi ve eri┼čiminizi m├╝mk├╝n oldu─čunca gizli tutmaya ├žal─▒┼č─▒n veya bunlar─▒ m├╝┼čterilere maruz b─▒rakmaktan ka├ž─▒n─▒n. Elbette kurucuda arg├╝man de─čerlerine sahip olabilirsiniz, ancak kapsam─▒ azaltarak m├╝┼čteri s─▒n─▒f─▒n─▒n ge├žersiz bir de─čer ge├žmesine izin vermezsiniz. De─čerleri de─či┼čtirmeniz gerekirse, her zaman yeni bir tane olu┼čturabilirsiniz object . Yap─▒c─▒daki de─čerleri yaln─▒zca bir kez kontrol edin ve y├Ântemlerin geri kalan─▒nda, de─čerlerin bo┼č olmad─▒─č─▒ndan hemen hemen emin olabilirsiniz.

Elbette, deneyim bu ├Âneriyi anlamak ve uygulamak i├žin daha iyi bir yoldur.

Bayt!


20







Muhtemelen Java 8 veya daha yenisi i├žin en iyi alternatif Optional s─▒n─▒f─▒ kullanmakt─▒r .

 Optional stringToUse = Optional.of("optional is there");
stringToUse.ifPresent(System.out::println);
 

Bu ├Âzellikle bo┼č de─čerlerin uzun zincirleri i├žin kullan─▒┼čl─▒d─▒r. ├ľrnek:

 Optional<Integer> i = Optional.ofNullable(wsObject.getFoo())
    .map(f -> f.getBar())
    .map(b -> b.getBaz())
    .map(b -> b.getInt());
 

Bo┼čta ├Âzel durumun nas─▒l at─▒laca─č─▒na ili┼čkin ├Ârnek:

 Optional optionalCarNull = Optional.ofNullable(someNull);
optionalCarNull.orElseThrow(IllegalStateException::new);
 

Java 7, Objects.requireNonNull bo┼č olmayan bir ┼čey i├žin kontrol edilmesi gerekti─činde kullan─▒┼čl─▒ olabilecek bir metodu tan─▒tt─▒ . ├ľrnek:

 String lowerVal = Objects.requireNonNull(someVar, "input cannot be null or empty").toLowerCase();
 

17







Daha genel olarak cevaplayabilir miyim?

Biz genellikle y├Ântemler bekledi─čimizden de─čil ┼čekilde parametreleri olsun bu sorunu y├╝z (k├Ât├╝ y├Ântem ├ža─čr─▒s─▒ programc─▒n─▒n hatam). ├ľrne─čin: bir nesne elde etmeyi umuyorsunuz, bunun yerine bo┼č. En az bir karakter i├žeren bir String almay─▒ bekliyorsunuz, bunun yerine bo┼č bir String al─▒yorsunuz ...

Yani aras─▒nda hi├žbir fark yoktur:

 if(object == null){
   //you called my method badly!
 

}

veya

 if(str.length() == 0){
   //you called my method badly again!
}
 

Her ikisi de ba┼čka fonksiyonlar yapmadan ├Ânce ge├žerli parametreler ald─▒─č─▒m─▒zdan emin olmak istiyor.

Di─čer baz─▒ cevaplarda da belirtildi─či gibi, yukar─▒daki sorunlardan ka├ž─▒nmak i├žin Design by s├Âzle┼čme modelini takip edebilirsiniz . L├╝tfen http://en.wikipedia.org/wiki/Design_by_contract adresini ziyaret edin .

Bu kal─▒b─▒ java'da uygulamak i├žin, javax.annotation.NotNull gibi ├žekirdek java ek a├ž─▒klamalar─▒n─▒ kullanabilir veya Hibernate Validator gibi daha geli┼čmi┼č k├╝t├╝phaneleri kullanabilirsiniz .

Sadece bir ├Ârnek:

 getCustomerAccounts(@NotEmpty String customerId,@Size(min = 1) String accountType)
 

Art─▒k, giri┼č parametrelerini kontrol etmeye gerek kalmadan metodunuzun temel fonksiyonunu g├╝venle geli┼čtirebilirsiniz, y├Ântemlerinizi beklenmeyen parametrelerden korurlar.

Bir ad─▒m daha ileri gidebilir ve ba┼čvurunuzda yaln─▒zca ge├žerli pojoslar─▒n olu┼čturuldu─čundan emin olabilirsiniz. (haz─▒rda bekleme do─črulay─▒c─▒ sitesinden ├Ârnek)

 public class Car {

   @NotNull
   private String manufacturer;

   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;

   @Min(2)
   private int seatCount;

   // ...
}
 

16







Her durumda bo┼č nesneleri kullanmay─▒ ├Âneren cevaplar─▒ kesinlikle g├Âz ard─▒ ediyorum. Bu ┼čablon s├Âzle┼čmeyi k─▒rabilir ve sorunlar─▒ ├ž├Âzmek yerine daha derin ve daha derindeki sorunlar─▒ g├Âmebilir, uygun olmayan bir ┼čekilde kullan─▒lmas─▒n─▒n gelecekteki bak─▒m gerektiren bir ba┼čka boyler kod kodu y─▒─č─▒n─▒ olu┼čturaca─č─▒ndan bahsetmez.

Ger├žekte, bir y├Ântemden d├Ând├╝r├╝len bir ┼čey bo┼č olabilir ve ├ža─č─▒ran kodun karar vermesi gerekiyorsa, devleti sa─člayan daha ├Ânceki bir ├ža─čr─▒ yap─▒lmal─▒d─▒r.

Ayr─▒ca, bo┼č nesne modelinin ├Âzenle kullan─▒l─▒rsa a├ž b─▒rak─▒laca─č─▒n─▒ unutmay─▒n. Bunun i├žin - bir NullObject ├Ârne─či sahipler aras─▒nda payla┼č─▒lmal─▒ ve bunlar─▒n her biri i├žin uygun olmayan bir ├Ârnek olmamal─▒d─▒r.

Ayr─▒ca, bu kal─▒b─▒, t├╝r├╝n ilkel bir t├╝r g├Âsterimi olmas─▒ gerekti─či - skaler olmayan matematiksel varl─▒klar gibi: vekt├Ârler, matrisler, karma┼č─▒k say─▒lar ve durum tutmas─▒ gereken POD (Plain Old Data) nesneleri olan bu modeli kullanman─▒z─▒ tavsiye etmem. Java yerle┼čik t├╝rleri ┼čeklinde. ─░kinci durumda, rasgele sonu├žlarla getter y├Ântemlerini ├ža─č─▒rman─▒z gerekir. ├ľrne─čin, NullPerson.getName () y├Ântemi ne d├Ând├╝rmelidir?

Sa├žma sonu├žlardan ka├ž─▒nmak i├žin bu gibi durumlar─▒ g├Âz ├Ân├╝nde bulundurmaya de─čer.


16







  1. De─či┼čkenleri asla null olarak ba┼člatmay─▒n.
  2. (1) m├╝mk├╝n de─čilse, t├╝m koleksiyonlar─▒ ve dizileri bo┼č koleksiyonlara / dizilere haz─▒rlay─▒n.

Bunu kendi kodunuzda yaparak ka├ž─▒nabilirsiniz! = Bo┼č kontroller.

Bo┼č ├žeklerin ├žo─ču, koleksiyonlar veya dizilerdeki d├Âng├╝leri korur gibi g├Âr├╝n├╝r, bu nedenle bo┼č b─▒rakt─▒ktan sonra bo┼č denetime gerek kalmaz.

 // Bad
ArrayList<String> lemmings;
String[] names;

void checkLemmings() {
    if (lemmings != null) for(lemming: lemmings) {
        // do something
    }
}



// Good
ArrayList<String> lemmings = new ArrayList<String>();
String[] names = {};

void checkLemmings() {
    for(lemming: lemmings) {
        // do something
    }
}
 

Bunda k├╝├ž├╝k bir ek y├╝k var, ancak daha temiz kod ve daha az NullPointerExceptions i├žin buna de─čer.


14







Bu, geli┼čtiricilerin ├žo─ču i├žin meydana gelen en yayg─▒n hatad─▒r.

Bununla ba┼ča ├ž─▒kmak i├žin bir├žok yolumuz var.

Yakla┼č─▒m 1:

 org.apache.commons.lang.Validate //using apache framework
 

notNull (Nesne nesnesi, Dize mesaj─▒)

Yakla┼č─▒m 2:

 if(someObject!=null){ // simply checking against null
}
 

Yakla┼č─▒m 3:

 @isNull @Nullable  // using annotation based validation
 

Yakla┼č─▒m 4:

 // by writing static method and calling it across whereever we needed to check the validation

static <T> T isNull(someObject e){  
   if(e == null){
      throw new NullPointerException();
   }
   return e;
}
 

14







 public static <T> T ifNull(T toCheck, T ifNull) {
    if (toCheck == null) {
           return ifNull;
    }
    return toCheck;
}
 

11



─░lgili yay─▒nlar


Bir denemede ger├žekten ne oldu {return x; } sonunda {x = null; } Beyan?

"─░f x: return x" ifadelerinden ka├ž─▒nman─▒n Pythonic yolu

G├Âr├╝n├╝m k├Âk├╝ olarak bo┼č ge├žmekten ka├ž─▒n─▒n (┼či┼čirilmi┼č d├╝zenin k├Âk ├Â─česindeki d├╝zen parametrelerini ├ž├Âzmeniz gerekir)

├ť├žl├╝ i┼čle├žle izin verilen bir int olarak bo┼č de─čer d├Ând├╝r├╝yor, ancak if ifadesi de─čil

─░fadeyi null nesnesiyle kullanma

String anahtar─▒ ifadesi neden bo┼č bir durumu desteklemiyor?

Bir for d├Âng├╝s├╝ i├žindeki ifadeden ka├ž─▒n─▒lmas─▒?

AlertDialog taraf─▒ndan kullan─▒lmak ├╝zere g├Âr├╝n├╝m ┼či┼čirilirken ÔÇťG├Âr├╝n├╝m k├Âk├╝ olarak bo┼č ge├žmekten ka├ž─▒n─▒nÔÇŁ uyar─▒s─▒

Her d├Âng├╝ yineleme ba┼člamadan ├Ânce bo┼č denetim ├Ânlemek i├žin bir yolu var m─▒?

VB.NET 'With' Beyan─▒ - kucaklamak m─▒ yoksa ka├ž─▒nmak m─▒?

Etiketle ilgili di─čer sorular [java]


C# 'de bir dizgi ba┼člatmak i├žin string.Empty veya String.Empty veya ÔÇťÔÇŁ kullanmal─▒ m─▒y─▒m?

Git havuzunda bir dizini nas─▒l do─čru ┼čekilde yeniden adland─▒rabilirim?

Bir XML dosyalar─▒n─▒ nas─▒l ayr─▒┼čt─▒r─▒r? [kapal─▒]

Visual Studio'da komut sat─▒r─▒ parametreleriyle hata ay─▒klama

XmlSerializer - T├╝r├╝n├╝ yans─▒tan bir hata olu┼čtu

├çift de─čeri 2 ondal─▒k basama─ča bi├žimlendirmenin en iyi yolu [kopya]

Bug├╝n├╝n tarihine g├╝n say─▒s─▒ nas─▒l eklenir? [├žift]

Sorgu dizgilerini Android'de ayr─▒┼čt─▒rma

p vs Ruby'yi koyar

Ba┼čka bir par├ža say─▒s─▒n─▒n par├žas─▒