1. Mga pagbubukod

>

Sa wakas, naisip ng mga programmer na i-standardize at i-automate ang paghawak ng error. Nangyari ito noong naimbento ang mga eksepsiyon . Ngayon ang mekanismo ng pagbubukod ay humahawak ng 80% ng mga pambihirang sitwasyon.

Kung ang ilang iskolar ay may mga eksepsiyon, malamang na ito ang paksa ng kanyang disertasyong pang-doktor. Kung naisip ito ng isang programmer, maaaring nakatanggap siya ng magiliw na tapik sa likod mula sa isang katrabaho: "Mukhang okay, bro."

Kapag may naganap na error sa isang Java program, tulad ng paghahati sa pamamagitan ng 0, ang ilang magagandang bagay ay nangyayari:

Unang hakbang

Ang isang espesyal na object ng exception ay nilikha, na naglalaman ng impormasyon tungkol sa error na naganap.

Ang lahat sa Java ay isang bagay, at ang mga eksepsiyon ay walang mga eksepsiyon 🙂 Ang mga bagay sa pagbubukod ay may sariling mga klase, at ang tanging bagay na nagpapaiba sa kanila mula sa mga ordinaryong klase ay ang pagmamana nila sa klase Throwable.

Ikalawang hakbang

Ang exception object ay "itinapon". Marahil ang mga salita dito ay maaaring maging mas mahusay. Ang "paghagis ng exception" ay mas katulad ng pagti-trigger ng alarma sa sunog o pagpapatunog ng alertong "DEFCON 1."

Kapag ang isang pagbubukod ay itinapon sa Java machine, ang normal na operasyon ng programa ay hihinto at magsisimula ang "mga emergency na protocol".

Ikatlong hakbang

Ang paraan kung saan ang pagbubukod ay itinapon ay lumabas kaagad. Ang pagbubukod ay ipinapasa sa paraan ng pagtawag, na agad ding lalabas. At iba pa pababa sa kadena hanggang sa mainlumabas ang pamamaraan. Kapag mainnatapos ang pamamaraan, ganoon din ang programa.

Halimbawa:

Code Output ng console
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

Ang isang pagbubukod ay nangyayari sa linya 20: paghahati ng 0. Ang Java machine ay agad na lumilikha ng isang pagbubukod - isang ArithmeticExceptionbagay at "itinapon" ito sa pamamaraan.

Ang divide()pamamaraan ay nagtatapos kaagad, kaya hindi namin nakikita ang string: Walang kakila-kilabot na nangyari: 0. Ang programa ay bumalik sa endTheWorld()pamamaraan, at ang sitwasyon ay nauulit mismo: mayroong isang hindi nahawakang pagbubukod sa system, na nangangahulugan na ang endTheWorld()pamamaraan ay nagwawakas din nang hindi normal. Pagkatapos ay magtatapos ang mainpamamaraan, at huminto ang programa.

Ano ang layunin ng mga pagbubukod na ito? Kaya, maaari kang sumulat ng iyong sariling code upang mahuli ang mga partikular na uri ng mga pagbubukod at isulat ang iyong sariling lohika upang mahawakan ang mga pambihirang sitwasyon.


2. Mga pagbubukod sa paghuli:try-catch

Ang Java ay may exception catching mechanism na hinahayaan kang ihinto ang abnormal na pagwawakas ng mga pamamaraan. Mukhang ganito:

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

Ang construct na ito ay tinatawag na try-catchblock.

Ang code kung saan maaaring mangyari ang mga pagbubukod ay nakabalot sa mga kulot na brace, na pinangungunahan ng salita try.

Pagkatapos ng mga kulot na braces, mayroon kaming catchkeyword at, sa loob ng mga panaklong, ang deklarasyon ng isang exception variable . Sinusundan ito ng mga kulot na brace na bumabalot sa code na ipapatupad kung may pagbubukod sa tinukoy na uri .

Kung walang mga pagbubukod na itinapon sa panahon ng pagpapatupad ng " pangunahing code ", kung gayon ang code sa loob ng catch block ay hindi isasagawa. Kung may mangyayaring exception, magiging (kung ang uri ng itinapon na exception ay kapareho ng uri ng variable sa mga panaklong).

Halimbawa:

Code Output ng console
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. Maramihang catchmga bloke

Maramihang mga catch block

Sa teorya, ang lahat ng uri ng mga pagbubukod ay maaaring itapon sa isang bloke ng code. Ang ilan ay gugustuhin mong pangasiwaan ang isang paraan, ang iba sa ibang paraan, at ang iba pa ay magpapasya kang huwag nang hawakan.

Nagpasya ang mga developer ng Java na tulungan ka at hayaan kang magsulat ng hindi isa ngunit maraming catchmga bloke pagkatapos ng trybloke.

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
}

Halimbawa:

Code Output ng console
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


4. Pagkakasunud-sunod ng catchmga bloke

Ang mga pagbubukod na nangyayari sa isang trybloke ay maaari lamang mahuli ng isang catchbloke. Hindi ka maaaring magkaroon ng exception sa paghawak ng sitwasyon kung saan ang code mula sa maraming catchmga bloke ay maipapatupad.

Ngunit ang pagkakasunud-sunod ng mga bloke ay mahalaga.

Maaari kang magkaroon ng isang sitwasyon kung saan ang isang pagbubukod ay maaaring makuha ng maraming mga bloke. Kung iyon ang kaso, ang exception ay mahuhuli ng alinmang catch block ang mauna (pinaka malapit sa tryblock).

Paano ka magkakaroon ng sitwasyon kung saan maraming catch block ang makakahuli ng parehong exception?

Ang lahat ng mga pagbubukod ay nabibilang sa isang hierarchy ng mana — tingnan ang diagram.

Exception hierarchy

ArithmeticExceptionMaaaring italaga ang isang bagay sa isang variable na ang uri ay ArithmeticExceptiono alinman sa mga ninuno nitong klase: RuntimeException , Exceptionat Throwable— tingnan ang diagram.

Pag-uusapan pa natin ang tungkol sa inheritance at ancestor class sa Level 21.

Ang code na ito ay mag-compile nang maayos:

Mga benepisyo ng mana:
ArithmeticException ae    = new ArithmeticException();
RuntimeException runtime  = new ArithmeticException();
Exception exception       = new ArithmeticException();
Throwable trwbl           = new ArithmeticException();

Para mahuli mo ang ArithmeticExceptionalinman sa 4 catchna bloke sa itaas.

Halimbawa 1:

Code Output ng console
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

Sa halimbawang ito, ang ArithmeticExceptionmaaaring mahuli ng parehong catch (Exception e)at catch (ArithmeticException e)mga bloke. Mahuhuli ito ng block na pinakamalapit sa tryblock — ang unang catchblock.

Upang maiwasan ang mga sorpresa, pinakamahusay na maglagay catchng mga bloke na maaaring makahuli sa halos lahat ng pagbubukod malapit sa dulo ng listahan ng catchmga bloke.

Ang Throwableuri ay karaniwang may kakayahang makuha ang bawat posibleng pagbubukod sa Java . Kung ilalagay mo ito sa unang catchbloke, hindi mako-compile ang code, dahil alam ng compiler na may mga hindi maabot na bloke ng code.