1. Kivételek

>

Végre a programozók arra gondoltak, hogy szabványosítják és automatizálják a hibakezelést. Ez akkor történt, amikor a kivételeket kitalálták. Most a kivételes mechanizmus kezeli a kivételes helyzetek 80%-át.

Ha néhány tudós kivételeket talált, az valószínűleg a doktori disszertációjának tárgya volt. Ha egy programozó találta ki, akkor lehet, hogy egy baráti vállveregetést kapott egy munkatársától: "Úgy tűnik, rendben van, tesó."

Ha hiba történik egy Java programban, például osztás -val 0, néhány csodálatos dolog történik:

Első lépés

Létrejön egy speciális kivételobjektum, amely információkat tartalmaz a felmerült hibáról.

A Java-ban minden objektum, és a kivételek nem kivételek 🙂 A kivételobjektumoknak saját osztályaik vannak, és az egyetlen dolog, ami megkülönbözteti őket a szokásos osztályoktól, az az, hogy öröklik az osztályt Throwable.

Második lépés

A kivétel objektum "dobott". Talán itt a megfogalmazás jobb lenne. A „kivételt dobni” inkább tűzriadó kiváltása vagy „DEFCON 1” riasztás megszólaltatása.

Amikor kivételt dob ​​a Java gép, a program normál működése leáll, és megkezdődnek a "vészprotokollok".

Harmadik lépés

Azonnal kilép az a módszer, amellyel a kivételt dobták. A kivételt a hívó metódus kapja, amely szintén azonnal kilép. És így tovább a láncon, amíg a mainmódszer ki nem lép. Amikor a mainmetódus véget ér, a program is lejár.

Példa:

Kód Konzol kimenet
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Your attention, please! Preparing for the end of the world");
      endTheWorld();
      System.out.println("The world ended successfully");
   }

   public static void endTheWorld()
   {
      System.out.println("We're doing something important");
      doSomeWork(0);
      System.out.println("Everything is working well");
   }

   public static void doSomeWork(int n)
   {
      System.out.println("Nothing terrible will happen: " + n);
      System.out.println(2 / n);
      System.out.println("Nothing terrible happened: " + n);
   }
}
Your attention, please! Preparing for the end of the world
We're doing something important
Nothing terrible will happen: 0

Kivétel történik a 20. sorban: osztás 0-val. A Java gép azonnal létrehoz egy kivételt – egy ArithmeticExceptionobjektumot, és „eldobja” a metódusnak.

A divide()metódus azonnal véget ér, így soha nem látjuk a karakterláncot: Nem történt semmi szörnyű: 0. A program visszatér a metódushoz endTheWorld(), és a helyzet megismétlődik: van egy kezeletlen kivétel a rendszerben, ami azt jelenti, hogy a endTheWorld()metódus is rendellenesen leáll. Ezután a mainmetódus leáll, és a program leáll.

Mi a célja ezeknek a kivételeknek? Nos, megírhatja saját kódját, hogy felfogjon bizonyos típusú kivételeket , és saját logikát írhat a kivételes helyzetek kezelésére.


2. Kivételek:try-catch

A Java rendelkezik egy kivételfogó mechanizmussal, amely lehetővé teszi a metódusok e rendellenes leállásának leállítását. Ez így néz ki:

try
{
   // Code where an exception might occur
}
catch(ExceptionType name)
{
   // Exception handling code
}

Ezt a konstrukciót blokknak nevezzük try-catch.

A kivételek előfordulásának kódja kapcsos zárójelekbe van foglalva, a szó előtt try.

A kapcsos kapcsos zárójelek után van a catchkulcsszó és zárójelben a kivételváltozó deklarációja . Ezt a kapcsos zárójelek követik , amelyek a végrehajtandó kódot tördelik, ha a megadott típusú kivétel előfordul .

Ha az " elsődleges kód " végrehajtása során nem adnak kivételt , akkor a catch blokkon belüli kód nem kerül végrehajtásra. Ha kivétel történik, akkor az is lesz (ha a kidobott kivétel típusa megegyezik a zárójelben lévő változó típusával).

Példa:

Kód Konzol kimenet
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Hadron Collider launched");

      try
      {
         launchHadronCollider(1);
         launchHadronCollider(0);
      }
      catch(Exception e)
      {
         System.out.println("Error! Caught an exception");
         System.out.println("The planet was sucked into a black hole!");
      }

      System.out.println("The Hadron Collider stopped");
   }

   public static void launchHadronCollider(int n)
   {
      System.out.println("Everything is working well: " + n);
      System.out.println(2/n);
      System.out.println("There are no problems: " + n);
   }
}
Hadron Collider launched
Everything is working fine: 1
2
There are no problems: 1
Everything is working fine: 0
Error! Caught an exception
The planet has been sucked into a black hole!
The Hadron Collider is stopped


3. Több catchblokk

Több fogási blokk

Elméletileg mindenféle kivételt be lehet dobni egy kódblokkba. Vannak, akikkel így, másokkal másképp akarsz majd foglalkozni, mások pedig úgy döntesz, hogy egyáltalán nem.

A Java fejlesztők úgy döntöttek, hogy segítenek Önnek, és hagyják, hogy ne egy, hanem több blokkot írjon a blokk catchután .try

try
{
   // Code where an exception might occur
}
catch (ExceptionType1 name1)
{
   // Code for handling ExceptionType1
}
catch (ExceptionType2 name2)
{
   // Code for handling ExceptionType2
}
   catch (ExceptionType3 name3)
{
   // Code for handling ExceptionType3
}

Példa:

Kód Konzol kimenet
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Start of main method");
      try
      {
         calculate(0);
      }
      catch (ArithmeticException e)
      {
         System.out.println("Division by 0");
      }
      catch(Exception e)
      {
         System.out.println("Caught some kind of exception");
      }

      System.out.println("End of main method");
   }

   public static void calculate(int n)
   {
      System.out.println("Start of calculate method: " + n);
      System.out.println(2/n);
      System.out.println("End of calculate method: " + n);
   }
}
Start of main method
Start of calculate method: 0
Division by 0
End of main method


catch4. A blokkok sorrendje

A blokkban előforduló kivételeket trycsak egyetlen catchblokk tudja elkapni. Nem lehet olyan kivételkezelési helyzet, amikor több blokkból származó kód catchvégrehajtásra kerül.

De a blokkok sorrendje számít.

Előfordulhat olyan helyzet, amikor egy kivételt több blokk is elkaphat. Ha ez a helyzet, akkor a kivételt az fogja elkapni, amelyik fogási blokk előbb érkezik (a blokkhoz legközelebb try).

Hogyan fordulhat elő olyan helyzet, amikor több fogási blokk is elkaphatja ugyanazt a kivételt?

Minden kivétel egyetlen öröklődési hierarchiához tartozik – lásd a diagramot.

Kivételi hierarchia

Egy ArithmeticExceptionobjektum hozzárendelhető egy változóhoz, amelynek típusa ArithmeticExceptionvagy valamelyik ősosztálya: RuntimeException , Exceptionés Throwable— lásd a diagramot.

A 21. szinten többet fogunk beszélni az öröklődésről és az ősök osztályairól.

Ez a kód jól lefordítható:

Az öröklés előnyei:
ArithmeticException ae    = new ArithmeticException();
RuntimeException runtime  = new ArithmeticException();
Exception exception       = new ArithmeticException();
Throwable trwbl           = new ArithmeticException();

ArithmeticExceptionÍgy a fenti 4 blokk bármelyikével elkaphat egyet catch.

1. példa:

Kód Konzol kimenet
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Start of main method");
      try
      {
         calculate(0);
      }
      catch(ArithmeticException e)
      {
         System.out.println("Division by 0");
      }
      catch(Exception e)
      {
         System.out.println("Caught some kind of exception");
      }

      System.out.println("End of main method");
   }

   public static void calculate(int n)
   {
      System.out.println("Start of calculate method: " + n);
      System.out.println(2/n);
      System.out.println("End of calculate method: " + n);
   }
}
Start of main method
Start of calculate method: 0
Division by 0
End of main method

Ebben a példában a és a blokkok ArithmeticExceptionis elkaphatják . A blokkhoz legközelebb eső blokk fogja el – az első blokk.catch (Exception e)catch (ArithmeticException e)trycatch

A meglepetések elkerülése érdekében a legjobb, ha a blokkok listájának végéhez közelcatch helyezi el azokat a blokkokat, amelyek szinte minden kivételt meg tudnak fogni .catch

A Throwabletípus általában képes minden lehetséges kivételt elkapni a Java-ban . Ha az első blokkba teszed catch, akkor a kód nem fordul le, mivel a fordító tudja, hogy vannak elérhetetlen kódblokkok.