9 klaidos, kurių reikia vengti programuojant "Java" kalba
Rafal Sawicki
"Java" programuotojas
Kokių klaidų reikėtų vengti programuojant "Java" kalba? Šiame straipsnyje atsakysime į šį klausimą.
Java yra populiari kalba, užimanti tvirtą vietą pasaulyje programinės įrangos kūrimas. Tai stipri ir universali programavimo kalba. Maždaug 3 mlrd. prietaisų visame pasaulyje veikia su Java todėl jį naudojant buvo padaryta mažiausiai 3 mlrd. klaidų. Šiame straipsnyje daugiausia dėmesio skirsime tam, kaip daugiau jų nedaryti.
1. Vienalaikio keitimo išimties gavimas
Tai bene dažniausiai pasitaikanti klaida, su kuria susidūriau. Savo karjeros pradžioje ir aš ją dariau daugybę kartų. Ši klaida įvyksta, kai bandote keisti kolekciją, kol ją iteruojate. Įrašas ConcurrentModificationException taip pat gali būti iškelta, kai dirbate su keliais srautais, tačiau dabar sutelkime dėmesį į pagrindinį scenarijų.
Tarkime, kad turite Kolekcija naudotojų, kai kurie iš jų yra suaugusieji, o kai kurie - ne. Jūsų užduotis - išfiltruoti vaikus.
for (Vartotojas : vartotojai) {
if (!user.isAdult()) {
users.remove(user);
}
}
Vykdant minėtą kodas baigiasi gavus ConcurrentModificationException. Kur suklydome? Prieš baigdami iteraciją pabandėme pašalinti kai kuriuos elementus. Dėl to ir atsirado išimtis.
Kaip to išvengti?
Tokiu atveju gali padėti keli būdai. Visų pirma, pasinaudokite Java 8 gerumas - Srautas.
List adults = users.stream()
.filter(User::isAdult)
.toList();
Naudojant Predikatas filtras, atlikome atvirkštinę ankstesnei sąlygai funkciją - dabar nustatome elementus, kuriuos reikia įtraukti. Tokio metodo privalumas yra tas, kad po pašalinimo lengva grandininiu būdu sujungti kitas funkcijas, pvz. žemėlapis. Bet dėl Dievo meilės. nebandykite daryti kažko panašaus į tai, kas aprašyta toliau:
Jis taip pat gali atsidurti ConcurrentModificationException nes keičiate srauto šaltinį. Be to, gali atsirasti daugiau išimčių, kurias bus nelengva pašalinti.
Išspręsti ConcurrentModificationException taip pat galite pereiti prie tiesioginio Iteratorius ir jo pašalinti() metodą, arba galite tiesiog nepašalinti elementų iteracijos metu. Tačiau aš rekomenduoju naudoti Srautai - 2022 m.
2. Slaptažodžių saugojimas kaip eilutės
Kadangi vis labiau įsitraukiu į kibernetinę saugą, nebūčiau teisingas sau, jei nepaminėčiau bent vieno "Java" klaida dėl to gali kilti saugumo problemų. Iš naudotojų gautų slaptažodžių saugojimas Stygos objektas yra būtent tai, ko turėtumėte bijoti.
Problema (o gal privalumas) Stygos yra tai, kad jis yra nekintamas. Kibernetiniame pasaulyje tai kelia potencialią grėsmę, nes negalima ištrinti kartą sukurtos vertės. Stygos objektas. Užpuolikas, gavęs prieigą prie jūsų kompiuterio atminties, joje gali rasti paprasto teksto slaptažodžius.
Antra, eilutės Java yra internuojami JVM ir saugomi PermGen erdvėje arba krūvos erdvėje. Kai sukuriate Stygos objektą, jis įrašomas į talpyklą ir pašalinamas tik tada, kai šiukšlių surinkėjas pradeda atlikti savo darbą. Negalite būti tikri, kada jūsų slaptažodis bus pašalintas iš "String" fondo, nes šiukšlių surinkėjas veikia nedeterministiškai.
Kaip to išvengti?
Rekomenduojama naudoti char[] arba, dar geriau, biblioteką, kuri palaiko slaptažodžių saugojimą kaip char[], pvz.Password4j. . char[] masyvą galima keisti, todėl po inicializavimo jį galima modifikuoti. Apdoroję slaptažodį, galite tiesiog ištrinti char[] slaptažodžių masyvą įrašydami į jį atsitiktinius simbolius. Jei įsilaužėliai gaus prieigą prie kompiuterio atminties, jie pamatys tik kelias atsitiktines reikšmes, kurios neturi nieko bendra su naudotojų slaptažodžiais.
3. Išimčių (ne)tvarkymas
Naujokai ir labiau pažengę programuotojai nežino, kaip teisingai tvarkyti išimtis. Pagrindinė jų nuodėmė šiuo klausimu - tiesiog jas ignoruoti. TAI NIEKADA NĖRA GERAS POŽIŪRIS.
Deja, negalime pateikti sprendimo, kuris tiktų kiekvienam Išimtiss" scenarijus, su kuriuo susiduriate. Apie kiekvieną atvejį turite galvoti atskirai. Tačiau galime patarti, kaip pradėti nagrinėti šią temą.
Kaip to išvengti?
Ignoruoti Išimtiss niekada nėra gera praktika. Išimtisįterpiamos dėl tam tikrų priežasčių, todėl nereikėtų jų ignoruoti.
try {...} catch(Išimtis e) { log(e); } retai kada yra teisingas požiūris į Išimtis tvarkymas.
Rethrow Išimtis, rodyti naudotojui klaidos dialogo langą arba bent jau įtraukti išsamų pranešimą į žurnalą.
Jei palikote neapdorotas išimtis (o taip neturėtų būti), bent jau paaiškinkite tai komentare.
4. Nulinės vertės naudojimas
Deja, gana dažnai pasitaiko "Java" funkcijų, kurios kai kuriais atvejais grąžina null. Problema yra ta, kad tokia funkcija priverčia klientą atlikti rezultato nulinį patikrinimą. Jei to nebūtų padaryta, NullPointerException išmetamas.
Kitas dalykas yra perduoti null vertė. Kodėl apie tai net pagalvojote? Tokiu atveju funkcija turi atlikti nulinės reikšmės patikrinimą. Kai naudojate trečiųjų šalių bibliotekas, negalite keisti funkcijų vidaus. Ką tada daryti?
Dar svarbiau, kad kiti kūrėjai, kurie skaito jūsų kodą ir mato, kad perduodate null tikriausiai nesuprasite, kodėl pasirinkote tokį keistą būdą savo funkcijai įgyvendinti.
Kaip to išvengti?
Negrąžinkite null vertė! Niekada! Jei jūsų funkcija grąžina tam tikro tipo Kolekcija, galite tiesiog grąžinti tuščią Kolekcija. Jei dirbate su pavieniais objektais, galite naudoti nulinio objekto projektavimo šabloną. Kadangi Java 8, jis įgyvendinamas kaip Pasirinktinai. Be to, mažiausiai rekomenduojamas būdas yra kelti Išimtis.
5. Sunkus eilutės sujungimas
Tikėkimės, kad tai nėra jūsų klaida, nes tai populiariausias (o gal antras pagal populiarumą po "FizzBuzz") interviu klausimas. Kaip jau turėtumėte žinoti, a Stygos objektas yra nekeičiamas Java - Kartą sukurtos, jos negalima keisti. Taigi konkatenavimas Stygos raidės reiškia daug nereikalingo atminties priskyrimo. sujungimas Stygos objektus kiekvieną kartą reikia sukurti laikiną StringBuilder objektą ir pakeičiant jį atgal į eilutę. Todėl šis sprendimas visiškai netinka, jei norime sujungti daug simbolių.
Kaip to išvengti?
Norėdami išspręsti šią problemą, naudokite StringBuilder. Taip sukuriamas keičiamas objektas, kuriuo galima lengvai manipuliuoti. Žinoma, visada galite naudoti StringBuffer jei jūsų projektas naudojamas lygiagrečiai.
6. Esamų sprendimų nenaudojimas
Kuriant programinę įrangą būtina išmanyti kalbos, kuria rašote, pagrindus, tačiau to nepakanka. Daugelį algoritminių problemų, su kuriomis susidūrėte įgyvendindami naują funkciją, jau išsprendė kas nors kitas. Pernelyg daug kartų mačiau, kaip kas nors įgyvendina saugumo algoritmą nuo nulio. Toks požiūris yra linkęs į klaidas. Vienas žmogus negali nuodugniai išbandyti tokio sudėtingo sprendimo. Kolektyvinės žinios komanda kurią sudaro vidutiniškai pažengę programuotojai, beveik visada yra geresnė už vieno stebuklingo programuotojo didybę. "Java" programuotojas. Nereikia išradinėti dviračio - tereikia pritaikyti esamą sprendimą pagal savo poreikius.
Kaip to išvengti?
Pabandykite ieškoti bibliotekų, kuriose sprendžiama problema, su kuria dirbate. Pabandykite rasti panašių sprendimų. Daugelis bibliotekų, kurias galima rasti žiniatinklio svetainė yra nemokamos, jas patobulino ir išbandė patyrę kūrėjai ir visa "Java" bendruomenė. Nebijokite jomis pasinaudoti.
7. Nerandama pakankamai laiko testams rašyti
Labai norisi tikėti, kad mūsų kodas visada veiks tobulai. Kodo testų nerašymas yra didžiausia nuodėmė Java programinės įrangos kūrėjai. Daugelis iš mus teikia pirmenybę rankiniams ir tiriamiesiems testams, o ne vienetų testams, o tai yra beprotiška. Kam gaišti laiką rašant testus, jei gali susitelkti į geriausio pasaulyje kodo, kuris tikrai neturi klaidų, pateikimą savo projektui?<joke>. Pasirodo, realybė yra žiauri ir mes negalime pateikti aukštos kokybės kodo nerašydami testų.
Kaip to išvengti?
Visada turėtumėte parengti savo kodo testus. Žinau, kad TDD metodą nėra taip lengva prižiūrėti, tačiau bent jau turėtumėte pateikti testus, kurie apimtų visas sąlygas, kuriomis jūsų kodas gali būti paleistas. Tai apima ir išskirtinių situacijų testavimą. Vieneto testai yra būtini. Juos turite pateikti kiekvienai savo projekto funkcijai, jei norite užtikrinti, kad jūsų kodą būtų lengva refaktorizuoti ir plėsti toliau jį vystant.
Dar vienas dalykas. Palaikykite aukštą savo bandomojo kodo standartą - bus verta. Tai dėdės Bobo patarimas, ir aš jam visiškai pritariu.
Be to, nepamirškite ir kitų tipų testų. Integracijos testai - tai dalykas, į kurį turėtumėte atsižvelgti kiekviename projekte.
8. Pamiršti prieigos modifikatorius
Privatus ir viešas, tiesa? Kaip galime juos pamiršti. Pasirodo, jų yra ir daugiau. Kai pirmą kartą pradėjote mokytis Java, tikrai sužinojote apie saugomus prieigos modifikatorius. Kai kuriais atvejais jie gali būti naudingi, todėl verta žinoti apie jų egzistavimą.
"Java" kūrėjai dažnai pamirštama apie paketo apimtį. Lengva nepamiršti apie jos naudojimą, nes ji yra numanoma ir nereikalauja jokių Java raktažodžiai. Paketo apimtis yra svarbi. Ji leidžia testuoti apsaugotą metodą. Apsaugoti elementai pasiekiami iš testuojamos klasės kelio, jei paketas yra tas pats.
Kaip to išvengti?
Nepamirškite apie saugomą modifikatorių ir tai, kad paketo apimtis leidžia jį išbandyti.
9. Grynosios JavaEE, o ne "Spring" naudojimas
Kitas žingsnis po mokymosi Java SE yra išmokti paleisti Java serveriuose, kaip sukurti įmonės lygmens programą.
Naujokai dažnai patenka į spąstus mokydamiesi JavaEE, nes apie ją yra daugybė vadovėlių. Netgi "Mąstymas Java "Java" programuotojai' biblijoje minima JavaEE ir nieko nekalbama apie kitas parinktis.
Kaip to išvengti?
"JavaEE" yra praeities daina. Šiandien "Spring" yra pagrindinis dalykas, o "Java EE" yra tiesiog gražus dalykas. Kiekviena šiuolaikinė įmonės lygio programa naudoja "Spring", todėl turėtumėte tvirtai apsvarstyti galimybę išmokti čia.