Venkite! = Null

NullPointerException object != null kad išvengtumėte „ NullPointerException .

Ar yra gera alternatyva?

Pavyzdžiui:

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

Taip išvengiama „ NullPointerException kai nežinoma, ar objektas yra null .

Atkreipkite dėmesį, kad priimtas atsakymas gali būti pasenęs, žr. ngn-wiki.ru.site/questions/50 / ... dėl vėlesnio požiūrio.

3608
07 нояб. pateikė Goran Martinic 07.11 . 2008-11-07 11:31 '08 at 11:31 am 2008-11-07 11:31
@ 60 atsakymų
  • 1
  • 2

Man atrodo, kaip gana dažna problema, kad jaunesni kūrėjai tam tikru momentu susiduria: jie nežino ar nepasitiki sutartimis, kuriose jie dalyvauja, ir ginti juos per daug nuliui. Be to, rašydami savo kodą, jie linkę pasikliauti nuliais, rodančiais kažką, kas reikalauja, kad skambintojas patikrintų nulius.

Kitaip tariant, yra du atvejai, kai atliekamas nulinis patikrinimas:

  • Kai null yra galiojantis atsakymas pagal sutartį; ir

  • Jei tai neteisingas atsakymas.

(2) lengva. Naudokite assert (teiginius) arba nepavyko (pvz., „ NullPointerException“ ). Pareiškimai yra labai mažai naudojama „Java“ funkcija, pridėta 1.4. Sintaksė:

 assert <condition> 

arba

 assert <condition> : <object> 

kur <condition> yra loginė išraiška, ir <object> yra objektas, o toString() metodo išvestis bus įtraukta į klaidą.

assert skambina Error ( AssertionError ), jei sąlyga nėra teisinga. Pagal nutylėjimą „Java“ ignoruoja teiginius. Galite įgalinti teiginius perduodami -ea parinktį JVM. Galite įjungti ir išjungti teiginius atskiroms klasėms ir paketams. Tai reiškia, kad jūs galite išbandyti kodą su teiginiais vystymosi ir bandymų metu ir išjungti juos gamybos aplinkoje, nors mano bandymai parodė, kad trūksta poveikio įtarimams.

Nenaudokite teiginių šiuo atveju, Gerai, nes kodas bus tik nesėkmingas, o tai atsitiks, jei naudosite tvirtinimus. Vienintelis skirtumas yra tas, kad su pareiškimais tai gali įvykti anksčiau, prasmingiau ir galbūt papildoma informacija, kuri gali padėti jums suprasti, kodėl taip atsitiko, jei to nesitikėjote.

(1) yra šiek tiek sudėtingesnis. Jei neturite jokio valdymo kodo, kurį skambinate, esate įstrigę. Jei null yra tinkamas atsakymas, turėtumėte jį patikrinti.

Jei tai yra kodas, kurį kontroliuojate (ir tai dažnai atsitinka), tai dar viena istorija. Nenaudokite nulio kaip atsakymo. Naudojant metodus, kurie grąžina kolekcijas, yra tuščias: tuščių kolekcijų (ar masyvų) grąžinimas vietoj nulio beveik visą laiką.

Su ne kolekcijomis, tai gali būti sudėtinga. Apsvarstykite tai kaip pavyzdį: jei turite šias sąsajas:

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

kur Parser trunka žaliavinio vartotojo įvestį ir suranda kažką, ką daryti, galbūt, jei kažkaip įgyvendinsite komandinės eilutės sąsają. Dabar galite sudaryti sutartį, kad ji grąžina nulį, jei nėra atitinkamo veiksmo. Tai lemia nulinį patikrinimą, apie kurį kalbate.

Alternatyvus sprendimas yra niekada negrąžinti null ir naudoti „Null Object“ šabloną :

 public class MyParser implements Parser { private static Action DO_NOTHING = new Action() { public void doSomething() {  } }; public Action findAction(String userInput) { // ... if (  ) { return DO_NOTHING; } } } 

Palyginimui:

 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(); } 

į

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

kuris yra daug geriau, nes jis sukelia daugiau suspausto kodo.

Tačiau gali būti absoliučiai būtina, kad findAction () metodas išmeta išimtį prasmingu klaidos pranešimu - ypač šiuo atveju, kai pasitikite vartotojo įvestimi. Būtų daug geriau, jei findAction metodas pasirinktų išimtį nei skambinančiojo metodo, kad būtų galima susprogdinti paprastą NullPointerException be paaiškinimo.

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

Arba, jei manote, kad bandymo / sugavimo mechanizmas yra pernelyg bjaurus ir neveikia nieko, numatytasis veiksmas turėtų suteikti naudotojų atsiliepimus.

 public Action findAction(final String userInput) {  return new Action() { public void doSomething() { userConsole.err("Action not found: " + userInput); } } } 
2422
07 нояб. Atsakymas suteiktas 07 lapkričio lapkričio mėn. 2008-11-07 15:06 '08 at 15:06 2008-11-07 15:06

Jei naudojate (arba planuojate naudoti) „Java IDE“, pvz., „ JetBrains IntelliJ IDEA“ , „Eclipse“ ar „Netbeans“, arba įrankį, pvz., „Findbugs“, galite išspręsti šią problemą anotacijomis.

Iš esmės turite @Nullable ir @NotNull .

Jūs galite naudoti metodą ir parametrus, pavyzdžiui:

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

arba

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

Antrasis pavyzdys nesudarys (IntelliJ IDEA).

Kai naudojate pirmąją „ helloWorld() funkciją kitame kodo fragmente:

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

Dabar „IntelliJ IDEA“ kompiliatorius pasakys, kad patikrinimas yra nenaudingas, nes „ helloWorld() funkcija negrąžinama.

Naudokite parametrą

 void someMethod(@NotNull someParameter) { } 
border=0

jei rašote kažką panašaus:

 someMethod(null); 

Tai nebus rengiama.

Naujausias pavyzdys naudojant „ @Nullable

 @Nullable iWantToDestroyEverything() { return null; } 

Tai padaryti

 iWantToDestroyEverything().something(); 

Ir jūs galite būti tikri, kad tai neįvyks. :)

Tai geras būdas leisti kompiliatoriui patikrinti daugiau nei įprastai ir sustiprinti savo sutartis. Deja, visus kompiliatorius nepalaiko.

„IntelliJ IDEA 10.5“ ir toliau jie palaikė bet kokius kitus „ @Nullable @NotNull .

Žr. Dienoraščio įrašą. Lankstesnės ir pritaikomos „@ Nullable / @ NotNull“ anotacijos .

528
05 марта '10 в 13:31 2010-03-05 13:31 Atsakymą pateikė Luca Molteni, kovo 05 '10, 13:31 2010-03-05 13:31

Jei nulinės vertės neleidžiamos

Jei jūsų metodas vadinamas išoriniu būdu, pradėkite nuo panašaus:

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

Tada likusioje šio metodo dalyje sužinosite, kad object nėra nulinis.

Jei tai yra vidinis metodas (kuris nėra API dalis), tiesiog dokumentuokite, kad jis negali būti nulinis ir kad jis yra.

Pavyzdys:

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

Tačiau, jei jūsų metodas paprasčiausiai praeina vertę, o kitas metodas jį perduoda ir tt, tai gali tapti problematiška. Tokiu atveju galite patikrinti pirmiau pateiktą argumentą.

Jei null yra leidžiama

Tai tikrai priklauso. Jei pastebėsite, kad dažnai tai darau:

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

Taigi, veisiu ir darau du visiškai skirtingus dalykus. Nėra bjauraus kodo fragmento, nes man reikia daryti du skirtingus dalykus, priklausomai nuo duomenų. Pavyzdžiui, ar turėčiau dirbti su įvestimi, ar turėčiau apskaičiuoti gerą numatytąją vertę?


Aš tikrai retai turiu naudoti, if (object != null ... ) idiomas.

Jums gali būti lengviau pateikti pavyzdžių, jei rodote pavyzdžius, kur paprastai naudojate idiomą.

286
07 нояб. atsakymą pateikė myplacedk 07.11 . 2008-11-07 12:27 '08, 12:27 pm 2008-11-07 12:27

Wow, beveik nenoriu pridėti kito atsakymo, kai turime 57 skirtingus būdus rekomenduoti „ NullObject pattern , bet manau, kad kai kurie žmonės, domisi šiuo klausimu, gali norėti sužinoti, kad lentelėje „Java 7 yra pasiūlymas pridėti „ „null-safe“ apdorojimas “ - supaprastinta sintaksė, jei logika yra ne-vienoda.

Alex Miller pateiktas pavyzdys yra toks:

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

?. reiškia tik atšaukti nuorodą į kairįjį identifikatorių, jei jis nėra nulinis, kitaip vertinti likusią išraišką kaip null . Kai kurie žmonės, pavyzdžiui, „Post“ narys „Dick Wall“ ir „ Devoxx“ rinkėjai , tikrai mėgsta šį pasiūlymą, tačiau yra prieštaravimas dėl to, kad jis iš tikrųjų paskatins didesnį null kaip kontrolės vertę.


Atnaujinimas: oficialus pasiūlymas, skirtas „Java 7“ operatoriui, buvo išsiųstas „ Project Coin“. Sintaksė šiek tiek skiriasi nuo aukščiau pateikto pavyzdžio, tačiau ta pati sąvoka.


Atnaujinti. Siūlomas pasiūlymas be saugaus operatoriaus nebuvo įtrauktas į projekto monetą. Taigi, ši sintaksė nebus matoma „Java 7“.

216
17 янв. atsakymą pateikė erickson, sausio 17 d 2009-01-17 08:08 '09, 08:08 am. 2009-01-17 08:08

Jei neapibrėžtos vertės neleidžiamos:

Galite nustatyti savo IDE, kad įspėtų jus apie galimą nulinį dereferenciją. Pavyzdžiui, „Eclipse“ žr. Nustatymai> Java> Kompiliatorius> Klaidos / įspėjimai / nulinė analizė.

Jei leistinos neapibrėžtos vertės:

Jei norite nustatyti naują API, kur neapibrėžtos reikšmės yra prasmingos, naudokite parinkties šabloną (jis gali būti susipažinęs su funkcinėmis kalbomis). Ji turi šiuos privalumus:

  • API aiškiai nurodo, ar įvestis ar išėjimas yra ar ne.
  • Kompiliatorius verčia tvarkyti „neapibrėžtą“ atvejį.
  • Šis variantas yra monadas , todėl nereikia patikrinti galiojančių nulių, tiesiog naudokite žemėlapį / foreach / getOrElse arba panašų kombinatorių, kad būtų saugiai naudojama vertė (pavyzdys) .

„Java 8“ turi Optional įmontuotą klasę (rekomenduojama); ankstesnėms versijoms yra bibliotekos alternatyvos, pavyzdžiui, „ Optional Guava Option arba „ FunctionalJava“ . Tačiau, kaip ir daugelis funkcinių šablonų, naudojant „Option“ programoje „Java“ (net 8) atsiranda gana mažas modelis, kurį galite sumažinti naudojant mažiau išsamią JVM kalbą, pvz., „Scala“ arba „Xtend“.

Jei reikia susidoroti su API, kuri gali grąžinti NULL reikšmes, „Java“ negali daug padaryti. Ar „Xtend“ ir „Groovy“ turi „Elvis“ operatorių ?: tačiau atkreipkite dėmesį, kad nulinės atskaitos atveju tai nulinė, taigi ji tiesiog atšaukia teisingą nulinės vertės tvarkymą.

178
14 янв. Atsakymas duotas „ Soft“ sausio 14 d 2010-01-14 16:45 '10, 16:45, 2010-01-14 16:45

Tik šiai situacijai -

Prieš patikrindami lygiavertį metodą, patikrinkite, ar kintamasis yra nulinis (žemiau pateikto eilutės palyginimo pavyzdys):

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

nulems NullPointerException jei foo nebus.

Tai galite išvengti, lygindami savo String taip:

 if ( "bar".equals(foo) ) { // ... } 
163
09 нояб. atsakymas pateikiamas 9 d. 2008-11-09 15:24 '08, 15:24, 2008-11-09 15:24

„Java 8“ - nauja klasė java.util.Optional , kuri, galbūt, išsprendžia kai kurias problemas. Galima net pasakyti, kad tai pagerina kodo įskaitomumą, o viešųjų API atveju supaprastina API sąsajos su kūrėjo klientu darbą.

Jie dirba taip:

Pasirenkamas šio tipo objektas ( Fruit ) sukuriamas kaip metodo grąžinimo tipas. Jis gali būti tuščias arba juose yra Fruit objektas:

 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(); } 

Dabar pažiūrėkite į šį kodą, kur ieškome Fruit sąrašo „ Fruit sąrašas“:

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

Galite naudoti map() operatorių atlikti skaičiavimą - arba gauti vertę iš pasirinktinio objekto. orElse() leidžia jums pateikti trūkstamų reikšmių atsarginę kopiją.

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

Žinoma, vis dar reikalingas nulinis / tuščias patikrinimas, tačiau bent jau kūrėjas žino, kad vertė gali būti tuščia, o rizika pamiršti tikrinti yra ribota.

API, pastatyta iš nulio naudojant Optional , kai grąžinimo vertė gali būti tuščia ir grąžina paprastą objektą tik tuo atveju, jei jis negali būti null (konvencija), kliento kodas gali atsisakyti nulinių patikrintų grąžintų objektų reikšmių ...

Žinoma, Optional taip pat gali būti naudojamas kaip metodo argumentas, galbūt geresnis būdas nurodyti pasirinktinius argumentus nei 5 arba 10 perkrovos metodų kai kuriais atvejais.

Optional siūlomi kiti patogūs metodai, pvz., „ orElse , kurie leidžia naudoti numatytąsias reikšmes, ir ifPresent , kuris veikia su lambda išraiškomis .

Kviečiu jus perskaityti šį straipsnį (mano pagrindinį atsakymo rašymo šaltinį), kuriame problema „ NullPointerException (ir apskritai nulinis žymeklis), taip pat (dalinis) „ Optional pateiktas sprendimas yra gerai paaiškinti: papildomi „Java“ objektai .

137
25 апр. Pierre Henry atsakymas, pateiktas balandžio 25 d 2013-04-25 18:22 '13, 18:22 PM 2013-04-25 18:22

Priklausomai nuo jūsų tikrinamų objektų, galite naudoti kai kurias klases bendromis „Apache“ frakcijomis, pvz .: apache commons > ir apache kolekcijų rinkinius

Pavyzdys:

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

arba (priklausomai nuo to, ką reikia patikrinti):

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

StringUtils klasė yra tik vienas iš daugelio; Bendruomenėse yra nemažai gerų klasių, kurios saugiai manipuliuoja.

Toliau pateikiamas pavyzdys, kaip galite naudoti „null vallidation“ JAVA, kai įgalinate „Apache“ biblioteką (commons->

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

O jei naudojate Pavasarį, Pavasaris taip pat turi tą pačią funkciją savo pakete, žiūrėkite biblioteką (pavasaris -2.4.6.jar)

Šios statinės klasės f panaudojimo pavasarį pavyzdys (org.springframework.util.Assert)

 Assert.notNull(validationEventHandler,"ValidationHandler not Injected"); 
113
07 нояб. atsakymas duotas javamonkey79 07 Lap. 2008-11-07 12:10 '08, 12:10 2008-11-07 12:10
  • Jei manote, kad objektas neturėtų būti nulinis (arba tai yra klaida), naudokite teiginį.
  • Jei jūsų metodas nepriima nulinių parametrų, pasakykite tai javadoc ir naudokite teiginį.

Jums reikia patikrinti objektą! = Null, tik jei norite tvarkyti atvejį, kai objektas gali būti tuščias ...

Siūloma į Java7 pridėti naujų komentarų, kad padėtų su null / notnull parametrais: http://tech.puredanger.com/java7/#jsr308

87
07 нояб. atsakymas pateikiamas pgras 07 lapkričio. 2008-11-07 11:55 '08 at 11:55 2008-11-07 11:55

Aš esu „nesėkmingo“ kodo gerbėjas. Paklauskite savęs: ar darai kažką naudingo, kai parametras yra nulis? Jei neturite aiškaus atsakymo į tai, ką jūsų kodas turėtų atlikti šiuo atveju ... ty, jis niekada neturėtų būti nulis, o tada jį ignoruoti ir leisti mesti NullPointerException. Skambintojo kodas turės tokią pačią NPE reikšmę kaip ir „IllegalArgumentException“ išimtis, tačiau kūrėjui bus lengviau derinti ir suprasti, kas atsitiko, jei NPE išmestas, o ne jūsų kodas, bandantis įvykdyti kai kuriuos kitus nenumatytus logikos nenumatytus įvykius, kurie galiausiai pasiekia tai, kad paraiška vis dar neveikia.

81
23 мая '11 в 21:18 2011-05-23 21:18 atsakymą pateikė Alex Worden gegužės 23 d. 11 d. 21:18 2011-05-23 21:18

Kartais yra būdų, kurie veikia su jo parametrais, kurie apibrėžia simetrinę operaciją:

 af(b); <-> bf(a); 

Jei žinote, kad b niekada negali būti nulis, galite tiesiog ją pakeisti. Tai naudingiausia lygiaverčiai: vietoj foo.equals("bar"); geriau padaryti "bar".equals(foo); .

69
07 нояб. Atsakymas suteiktas Johannes Schaub - litb 07.11 . 2008-11-07 12:04 '08, 12:04 2008-11-07 12:04

„Google“ kolekcijų struktūra suteikia gražią ir elegantišką būdą pasiekti nulinį patvirtinimą.

Bibliotekos klasė turi metodą:

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

Ir naudojamas (su import static ):

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

Arba savo pavyzdyje:

 checkNotNull(someobject).doCalc(); 
69
29 дек. atsakymą pateikė vartotojo2427 29 d. 2008-12-29 16:50 '09, 16:50, 2008-12-29 16:50

Vietoj nulinio objekto modelio, kuris naudoja savo paskirtį, galite apsvarstyti situacijas, kai nulinis objektas yra klaida.

Kai išimtis išimta, peržiūrėkite kamino pėdsaką ir padarykite klaidą.

67
07 нояб. Jim Nelson atsakė į lapkričio 7 d. 2008-11-07 11:50 '08, 11:50, 2008-11-07 11:50

„Java 7“ turi naują java.util.Objects naudingumo klasę, kurioje yra reikalavimo requireNonNull() . Visa tai daro „ NullPointerException jei jos argumentas yra nulinis, tačiau jis šiek tiek išvalo kodą. Pavyzdys:

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

Metodas yra naudingiausias tikrinant prieš pat paskyrimą konstruktoriuje, kur kiekvienas jo naudojimas gali išsaugoti tris kodo eilutes:

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

tampa

 Parent(Child child) { this.child = Objects.requireNonNull(child, "child"); } 
65
10 авг. Stuart Marks atsakymas, rugpjūčio 10 d. 2012-08-10 10:08 '12, 10:08, 2012-08-10 10:08

Nulis nėra problema. Jis yra sudėtinė visapusiško modeliavimo įrankių dalis. Programinės įrangos tikslas - imituoti pasaulio sudėtingumą, o nuliui tenka našta. „Null“ „ Java“ ir pan. Reiškia „No data“ arba „Unknown“ . Todėl šiais tikslais patartina naudoti nulles. Nenoriu naudoti „Nulinio objekto“ modelio; Manau, kad jis kelia „ kas gins globėjų klausimą“.
Jei manęs paklaustumėte, kas yra mano draugės vardas, aš jums pasakysiu, kad neturiu merginos. „Java“ grįšiu nulį. Alternatyva būtų išmesti protingą išimtį, kad būtų galima atkreipti dėmesį į tam tikrą problemą, kuri negali būti (ar nenori būti) išspręsta ten, ir perduoti ją kažkur aukščiau ant kamino, kad bandytų iš naujo arba pranešti apie klaidą, kai naudotojui pasiekiama duomenų.

  1. Už „nežinomą klausimą“ pateikite „nežinomą atsakymą“. (Tai yra nesaugi, jei ji yra tinkama verslo požiūriu). Nulinio argumento tikrinimas prieš naudojimą metode prieš kelis skambučius išlaisvina kelis skambinančius asmenis.

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

    Ankstesnis sukelia normalų loginį srautą, kad galėčiau gauti nuotrauką iš nežinomos merginos iš mano nuotraukų bibliotekos.

     getPhotoOfThePerson(me.getGirlfriend()) 

    Ir tai atitinka naują „Java“ API (laukiame).

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

    Nors „normalus verslo srautas“ neleidžia jums rasti asmeniui duomenų bazėje saugomos nuotraukos, kai kuriais kitais atvejais naudoju pora, kaip parodyta žemiau.

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

    Ir jūs neturėtumėte nekensti rašyti <alt> + <shift> + <j> (generuoti javadoką „Eclipse“) ir parašyti tris papildomus žodžius viešajai API. Tai bus daugiau nei pakankamai visiems, išskyrus tuos, kurie neskaito dokumentacijos.

      

    arba

      
  2. Tai gana teorinis atvejis, ir daugeliu atvejų turėtumėte pirmenybę teikti „Java“ nulio saugiam API (jei jis išleistas po 10 metų), tačiau „ NullPointerException yra Exception poklasis. Taigi tai yra Throwable forma, nurodanti sąlygas, kurias priimtina programa gali sugauti ( javadoc )! Jei norite naudoti pirmąjį privilegijos pranašumą ir atskirą klaidų tvarkymo kodą iš „normalaus“ kodo ( pagal „Java“ kūrėjus ), tikslinga, kaip ir aš, sugauti „ NullPointerException .

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

    Gali būti klausimų:

    В. Что если getPhotoDataSource() возвращает значение null?
    О. Это деловая логика. Если мне не удастся найти фотоальбом, я покажу вам никаких фотографий. Что делать, если appContext не инициализирован? Этот метод бизнес-логики справляется с этим. Если одна и та же логика должна быть более строгой, то бросание исключения является частью бизнес-логики, а явная проверка на нуль должна использоваться (случай 3). Новый Java Null-safe API лучше подходит для того, чтобы указать выборочно, что подразумевает, и что не означает, что его инициализация будет неудачной в случае ошибок программиста.

    Q. Резервный код может быть выполнен и ненужные ресурсы могут быть захвачены.
    A. Это может произойти, если getPhotoByName() попытается открыть соединение с базой данных, создать PreparedStatement и, наконец, использовать имя человека в качестве параметра SQL. Подход к неизвестному вопросу дает неизвестный ответ (случай 1). Перед захватом ресурсов метод должен проверять параметры и при необходимости возвращать "неизвестный" результат.

    Q. Этот подход имеет штраф за производительность из-за открытия закрытия попытки.
    A. Программное обеспечение должно быть легко понятным и модифицированным во-первых. Только после этого можно было подумать о производительности, и только в случае необходимости! и там, где это необходимо! ( источник ) и многие другие).

    Ps. Такой подход будет разумным использовать, поскольку отдельный код обработки ошибок из "обычного" принципа кода разумно использовать в некотором месте. Рассмотрим следующий пример:

     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. Для тех, кто быстро сжимается (и не так быстро читает документацию), я хотел бы сказать, что в своей жизни я никогда не видел исключения с нулевым указателем (NPE). Но эта возможность была специально разработана разработчиками Java, потому что NPE является подклассом Exception . У нас есть прецедент в истории Java, когда ThreadDeath является Error не потому, что на самом деле это ошибка приложения, а исключительно потому, что он не предназначен для того, чтобы быть пойманным! Сколько NPE подходит для Error чем ThreadDeath ! Но это не так.

  3. Проверьте "Нет данных" только в том случае, если это подразумевает бизнес-логика.

     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); } } 

    ir taip pat

     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 или dataSource не инициализируется необработанной рабочей средой, NullPointerException убьет текущий поток и будет обработан Thread.defaultUncaughtExceptionHandler (для определения и использования вашего любимого регистратора или другого механизма уведомления). Если не задано, ThreadGroup # uncaughtException будет печатать stacktrace для системного err. Необходимо отслеживать журнал ошибок приложений и открывать проблему Jira для каждого необработанного исключения, которое на самом деле является ошибкой приложения. Программист должен исправить ошибку где-то в файле инициализации.

63
ответ дан Mykhaylo Adamovych 21 нояб. '11 в 15:58 2011-11-21 15:58