1. A kivételek típusai
Minden kivétel 4 típusra oszlik, amelyek valójában egymást öröklik osztályok.
Throwableosztály
Az összes kivétel alaposztálya az Throwableosztály. Az Throwableosztály tartalmazza azt a kódot, amely az aktuális hívási veremet (az aktuális metódus veremnyomát) egy tömbbe írja. Kicsit később megtudjuk, mi az a veremnyom.
A dobás operátor csak olyan objektumot tud elfogadni, amely az osztályból származik Throwable. És bár elméletileg írhat olyan kódot, mint a throw new Throwable();, ezt általában senki sem csinálja. Az osztály fő célja, Throwablehogy minden kivételre egyszülős osztály legyen.
Errorosztály
A következő kivételosztály az Errorosztály, amely közvetlenül örökli az Throwableosztályt. A Java gép létrehozza az osztály objektumait Error(és leszármazottjait), ha komoly problémák lépnek fel . Például hardverhiba, elégtelen memória stb.
Általában programozóként nem tud mit tenni olyan helyzetben, amikor egy ilyen hiba (olyan, amiért egy-t Errorkell dobni) történt a programban: ezek a hibák túl súlyosak. Nem tehet mást, mint értesíti a felhasználót, hogy a program összeomlik, és/vagy a hibáról minden ismert információt beír a programnaplóba.
Exceptionosztály
A Exceptionés RuntimeExceptionosztályok a sok metódus működése során előforduló gyakori hibákra szolgálnak. Minden dobott kivétel célja, hogy elkapja egy catchblokk, amely tudja, hogyan kell megfelelően kezelni.
Ha egy metódus valamilyen okból nem tudja befejezni a munkáját, azonnal értesítenie kell a hívó metódust a megfelelő típusú kivétel dobásával.
Más szóval, ha egy változó egyenlő -val null, akkor a metódus egy -et dob NullPointerException. Ha helytelen argumentumokat adtunk át a metódusnak, akkor egy InvalidArgumentException. Ha a metódus véletlenül nullával oszt, akkor egy ArithmeticException.
RuntimeExceptionosztály
RuntimeExceptionsrészhalmaza a Exceptions. Akár azt is mondhatnánk, hogy RuntimeExceptiona szokásos kivételek ( ) könnyített változata Exception– kevesebb követelmény és korlátozás vonatkozik az ilyen kivételekre
ExceptionKésőbb megtanulod, mi a különbség a és a között RuntimeException.
2. Throws: ellenőrzött kivételek

Minden Java-kivétel 2 kategóriába sorolható: bejelölt és nem bejelölt .
Minden kivétel, amely örökli a RuntimeExceptionvagy a vagy a Errorbejelöletlen kivételeket . Az összes többi ellenőrzött kivétel .
Húsz évvel az ellenőrzött kivételek bevezetése után szinte minden Java programozó ezt hibának tartja. A népszerű modern keretrendszerekben a kivételek 95%-a nincs bejelölve. A C# nyelv, amely majdnem pontosan másolta a Java-t, nem adott hozzá ellenőrzött kivételeket .
Mi a fő különbség a bejelölt és a nem ellenőrzött kivételek között?
Az ellenőrzött kivételekre további követelmények vonatkoznak . Nagyjából ezek a következők:
1. követelmény
Ha egy metódus ellenőrzött kivételt dob , akkor az aláírásában jeleznie kell a kivétel típusát . Így minden hívó metódus tudatában van annak, hogy ez az "értelmes kivétel" előfordulhat benne.
A bejelölt kivételeket a kulcsszó után a metódusparaméterekthrows után tüntesse fel (ne használja throwvéletlenül a kulcsszót). Valahogy így néz ki:
type method (parameters) throws exception
Példa:
| ellenőrzött kivétel | ellenőrizetlen kivétel |
|---|---|
|
|
A jobb oldali példában a kódunk egy ellenőrizetlen kivételt dob – nincs szükség további teendőkre. A bal oldali példában a metódus ellenőrzött kivételt dob, így a throwskulcsszó hozzáadódik a metódus aláírásához a kivétel típusával együtt.
Ha egy metódus több ellenőrzött kivételt vár , akkor mindegyiket meg kell adni a throwskulcsszó után, vesszővel elválasztva. A sorrend nem fontos. Példa:
public void calculate(int n) throws Exception, IOException
{
if (n == 0)
throw new Exception("n is null!");
if (n == 1)
throw new IOException("n is 1");
}
2. követelmény
Ha olyan metódust hív meg, amelynek aláírása kivételeket ellenőrzött , nem hagyhatja figyelmen kívül azt a tényt, hogy kidobja azokat.
Az összes ilyen kivételt meg kell kapnia úgy, hogy catchmindegyikhez blokkokat ad hozzá, vagy hozzá kell adnia őket athrows metódushoz tartozó záradékhoz .
Mintha azt mondanánk: " Ezek a kivételek annyira fontosak, hogy meg kell fognunk őket. És ha nem tudjuk, hogyan kezeljük őket, akkor mindenkit értesíteni kell, aki hívja a módszerünket, hogy előfordulhatnak benne ilyen kivételek.
Példa:
Képzeld el, hogy írunk egy módszert egy emberek által lakott világ létrehozására. A kezdeti létszámot adják át érvként. Tehát kivételeket kell hozzáadnunk, ha túl kevés ember van.
| Föld teremtése | jegyzet |
|---|---|
|
A módszer potenciálisan két ellenőrzött kivételt dob:
|
Ez a metódushívás háromféleképpen kezelhető:
1. Ne ragadj el semmilyen kivételt
Ezt leggyakrabban akkor teszik meg, ha a módszer nem tudja, hogyan kell megfelelően kezelni a helyzetet.
| Kód | jegyzet |
|---|---|
|
A hívási metódus nem fogja fel a kivételeket, és tájékoztatnia kell róluk másokat: hozzáadja azokat a saját throwszáradékához |
2. Fogjon meg néhány kivételt
Mi kezeljük azokat a hibákat, amelyeket kezelni tudunk. De akiket nem értünk, azokat feldobjuk a hívásmódra. Ehhez hozzá kell adnunk a nevüket a dobás záradékhoz:
| Kód | jegyzet |
|---|---|
|
A hívó csak egy ellenőrzött kivételt észlel – LonelyWorldException. A másik kivételt hozzá kell adni az aláírásához, a throwskulcsszó után jelezve |
3. Fogja meg az összes kivételt
Ha a metódus nem tesz kivételt a hívó metódus alól, akkor a hívó metódus mindig biztos abban, hogy minden jól működött. És nem tud semmilyen intézkedést tenni a kivételes helyzetek megoldására.
| Kód | jegyzet |
|---|---|
|
Ez a módszer minden kivételt megragad. A hívó biztos abban, hogy minden rendben ment. |
3. Burkolási kivételek
Az ellenőrzött kivételek elméletben menőnek tűntek, de a gyakorlatban óriási csalódásnak bizonyultak.
Tegyük fel, hogy van egy rendkívül népszerű módszer a projektjében. A programodban több száz helyről hívják. És úgy dönt, hogy hozzáad egy új ellenőrzött kivételt. És könnyen lehet, hogy ez az ellenőrzött kivétel valóban fontos és annyira különleges, hogy csak a main()metódus tudja, mit kell tenni, ha elkapják.
Ez azt jelenti, hogy hozzá kell adnia a bejelölt kivételt throwsminden olyan metódus záradékához, amely a szupernépszerű metódusát hívja meg . Valamint throwsaz összes olyan metódus záradékában, amely ezeket a metódusokat hívja. És azokról a módszerekről, amelyek ezeket a módszereket hívják.
Ennek eredményeként throwsa projektben a metódusok felének záradékai új ellenőrzött kivételt kapnak. És természetesen a projektjét tesztek fedik le, és most a tesztek nem fordítódnak le. És most szerkesztened kell a dobások záradékait is a tesztekben.
Ezután az összes kódot (a több száz fájlban lévő összes változást) más programozóknak át kell nézniük. És ezen a ponton feltesszük magunknak a kérdést, hogy miért hajtottunk végre annyi véres változtatást a projekten? Munkanap(ok) és hibás tesztek – mindez csak egy ellenőrzött kivétel hozzáadásának kedvéért ?
És természetesen továbbra is vannak problémák az örökléssel és a módszer felülbírálásával kapcsolatban. Az ellenőrzött kivételekből származó problémák sokkal nagyobbak, mint a haszon. A lényeg az, hogy ma már kevesen szeretik és kevesen használják.
Azonban még mindig sok olyan kód van (beleértve a szabványos Java könyvtári kódot is), amely ezeket az ellenőrzött kivételeket tartalmazza. Mi a teendő velük? Nem hagyhatjuk figyelmen kívül őket, és nem tudjuk, hogyan kezeljük őket.
A Java programozók azt javasolták, hogy az ellenőrzött kivételeket csomagolja be RuntimeException. Más szóval, fogja meg az összes ellenőrzött kivételt, majd hozzon létre nem ellenőrzött kivételeket (például RuntimeException), és dobja el őket. Ez valahogy így néz ki:
try
{
// Code where a checked exception might occur
}
catch(Exception exp)
{
throw new RuntimeException(exp);
}
Nem túl szép megoldás, de nincs itt semmi bűnöző: a kivételt egyszerűen egy RuntimeException.
Ha szükséges, onnan könnyen visszakeresheti. Példa:
| Kód | jegyzet |
|---|---|
|
A kivétel tárolása az RuntimeExceptionobjektumon belül. A causeváltozó esetleg nullMeghatározza a típusát, és konvertálja ellenőrzött kivételtípussá. |
4. Több kivétel elkapása
A programozók nagyon utálják a kód megkettőzését. Még egy megfelelő fejlesztési elvet is kitaláltak: Ne ismételd magad (SZÁRAZ) . A kivételek kezelésekor azonban gyakran előfordulnak olyan esetek, amikor egy blokkot több azonos kódú blokk trykövet .catch
Vagy lehet 3 catchblokk ugyanazzal a kóddal és további 2 catchblokk más azonos kóddal. Ez egy szokásos helyzet, amikor a projekt felelősen kezeli a kivételeket.
A 7-es verziótól kezdődően a Java nyelv több típusú kivételt is megadhat egyetlen blokkban catch. Valahogy így néz ki:
try
{
// Code where an exception might occur
}
catch (ExceptionType1 | ExceptionType2 | ExceptionType3 name)
{
// Exception handling code
}
Annyi blokkja lehet, amennyit catchcsak akar. Egyetlen catchblokk azonban nem határozhat meg olyan kivételeket, amelyek öröklik egymást. Más szóval, nem írhatod a catch ( Exception| RuntimeExceptione) kifejezést, mert az RuntimeExceptionosztály örökli a -t Exception.
5. Egyéni kivételek
Mindig létrehozhat saját kivételosztályt. Egyszerűen létrehoz egy osztályt, amely örökli az RuntimeExceptionosztályt. Valahogy így fog kinézni:
class ClassName extends RuntimeException
{
}
Megbeszéljük a részleteket, miközben megtanulja az OOP-t, az öröklődést, a konstruktorokat és a metódusok felülbírálását.
Ha azonban csak egy ilyen egyszerű osztályod van (teljesen kód nélkül), akkor is dobhatsz kivételeket az alapján:
| Kód | jegyzet |
|---|---|
|
Dobj egy ellenőrizetlen MyException . |
A Java Multithreading küldetés során mélyen elmerülünk a saját egyéni kivételeinkkel való munka során.
GO TO FULL VERSION