1. Mga uri ng eksepsiyon

Ang lahat ng mga pagbubukod ay nahahati sa 4 na uri, na talagang mga klase na nagmamana sa isa't isa.

Throwableklase

Ang batayang klase para sa lahat ng mga pagbubukod ay ang Throwableklase. Ang Throwableklase ay naglalaman ng code na nagsusulat ng kasalukuyang call stack (stack trace ng kasalukuyang pamamaraan) sa isang array. Malalaman natin kung ano ang stack trace sa ibang pagkakataon.

Ang throw operator ay maaari lamang tumanggap ng isang bagay na nagmula sa Throwableklase. At kahit na maaari kang magsulat ng code tulad ng throw new Throwable();, walang sinuman ang karaniwang gumagawa nito. Ang pangunahing layunin ng Throwableklase ay magkaroon ng isang solong magulang na klase para sa lahat ng mga pagbubukod.

Errorklase

Ang susunod na klase ng exception ay ang Errorklase, na direktang nagmamana sa Throwableklase. Ang makina ng Java ay lumilikha ng mga bagay ng Errorklase (at ang mga inapo nito) kapag may naganap na mga seryosong problema . Halimbawa, isang malfunction ng hardware, hindi sapat na memorya, atbp.

Karaniwan, bilang isang programmer, wala kang magagawa sa isang sitwasyon kung saan ang ganitong error (ang uri kung saan Errordapat itapon) ay naganap sa programa: ang mga error na ito ay masyadong seryoso. Ang magagawa mo lang ay abisuhan ang user na nag-crash ang program at/o isulat ang lahat ng kilalang impormasyon tungkol sa error sa log ng program.

Exceptionklase

Ang Exceptionat RuntimeExceptionmga klase ay para sa mga karaniwang error na nangyayari sa pagpapatakbo ng maraming pamamaraan. Ang layunin ng bawat itinapon na pagbubukod ay mahuli ng isang catchbloke na nakakaalam kung paano ito maayos na pangasiwaan.

Kapag hindi makumpleto ng isang paraan ang gawain nito sa ilang kadahilanan, dapat nitong ipaalam kaagad ang paraan ng pagtawag sa pamamagitan ng paglalagay ng pagbubukod sa naaangkop na uri.

Sa madaling salita, kung ang isang variable ay katumbas ng null, ang pamamaraan ay magtapon ng isang NullPointerException. Kung ang mga maling argumento ay naipasa sa pamamaraan, ito ay magtapon ng isang InvalidArgumentException. Kung ang pamamaraan ay hindi sinasadyang nahati sa zero, ito ay magtapon ng isang ArithmeticException.

RuntimeExceptionklase

RuntimeExceptionsay isang subset ng Exceptions. Maaari pa nga nating sabihin na iyon RuntimeExceptionay isang magaan na bersyon ng mga ordinaryong eksepsiyon ( Exception) — mas kaunting mga kinakailangan at paghihigpit ang ipinapataw sa mga naturang eksepsiyon

Malalaman mo ang pagkakaiba sa pagitan ng Exceptionat RuntimeExceptionmamaya.


2. Throws: nasuri ang mga pagbubukod

Ang lahat ng Java exception ay nahahati sa 2 kategorya: may check at uncheck .

Lahat ng mga pagbubukod na nagmamana ng RuntimeExceptiono Erroritinuturing na mga hindi nasuri na mga pagbubukod . Lahat ng iba ay nasuri na mga eksepsiyon .

Mahalaga!

Dalawampung taon pagkatapos ng mga naka-check na eksepsiyon ay ipinakilala, halos lahat ng Java programmer ay nag-iisip na ito ay isang bug. Sa mga sikat na modernong framework, 95% ng lahat ng mga exception ay walang check. Ang wikang C#, na halos eksaktong kinopya ang Java, ay hindi nagdagdag ng mga naka-check na exception .

Ano ang pangunahing pagkakaiba sa pagitan ng mga naka-check at hindi na-check na mga exception?

May mga karagdagang kinakailangan na ipinapataw sa mga naka-check na exception. Sa halos pagsasalita, ang mga ito ay ito:

Kinakailangan 1

Kung ang isang paraan ay naghagis ng may check na exception , dapat itong ipahiwatig ang uri ng exception sa lagda nito . Sa ganoong paraan, alam ng bawat paraan na tumatawag dito na ang "makabuluhang pagbubukod" na ito ay maaaring mangyari dito.

Ipahiwatig ang mga may check na exception pagkatapos ng mga parameter ng pamamaraan pagkatapos ng throwskeyword (huwag gamitin ang throwkeyword nang hindi sinasadya). Mukhang ganito:

type method (parameters) throws exception

Halimbawa:

sinuri ang pagbubukod walang check na exception
public void calculate(int n) throws Exception
{
   if (n == 0)
      throw new Exception("n is null!");
}
public void calculate(n)
{
   if (n == 0)
      throw new RuntimeException("n is null!");
}

Sa halimbawa sa kanan, ang aming code ay naghagis ng hindi naka-check na exception — walang karagdagang aksyon ang kinakailangan. Sa halimbawa sa kaliwa, ang pamamaraan ay nagtatapon ng may check na exception, kaya ang throwskeyword ay idinagdag sa method signature kasama ang uri ng exception.

Kung inaasahan ng isang paraan na maghagis ng maramihang mga naka-check na exception, lahat ng mga ito ay dapat na tukuyin pagkatapos ng throwskeyword, na pinaghihiwalay ng mga kuwit. Ang order ay hindi mahalaga. Halimbawa:

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

Kinakailangan 2

Kung tatawagan mo ang isang paraan na nagsuri ng mga pagbubukod sa lagda nito, hindi mo maaaring balewalain ang katotohanan na itinapon nito ang mga ito.

Dapat mong mahuli ang lahat ng naturang mga pagbubukod sa pamamagitan ng pagdaragdag catchng mga bloke para sa bawat isa, o sa pamamagitan ng pagdaragdag ng mga ito sa isang throwssugnay para sa iyong pamamaraan.

Para bang sinasabi natin, " Napakahalaga ng mga eksepsiyon na ito kaya dapat nating hulihin ang mga ito. At kung hindi natin alam kung paano haharapin ang mga ito, kung gayon ang sinumang maaaring tumawag sa ating pamamaraan ay dapat na maabisuhan na ang gayong mga eksepsiyon ay maaaring mangyari dito.

Halimbawa:

Isipin na nagsusulat kami ng isang paraan upang lumikha ng isang mundo na pinaninirahan ng mga tao. Ang paunang bilang ng mga tao ay ipinasa bilang argumento. Kaya kailangan nating magdagdag ng mga pagbubukod kung napakakaunting tao.

Lumilikha ng Earth Tandaan
public void createWorld(int n) throws EmptyWorldException, LonelyWorldException
{
   if (n == 0)
      throw new EmptyWorldException("There are no people!");
   if (n == 1)
      throw new LonelyWorldException ("There aren't enough people!");
   System.out.println("A wonderful world was created. Population: " + n);
}
Ang pamamaraan ay potensyal na magtapon ng dalawang naka-check na mga pagbubukod:

  • EmptyWorldException
  • LonelyWorldException

Ang tawag sa pamamaraang ito ay maaaring pangasiwaan sa 3 paraan:

1. Huwag mahuli ang anumang mga pagbubukod

Ito ay madalas na ginagawa kapag ang pamamaraan ay hindi alam kung paano maayos na pangasiwaan ang sitwasyon.

Code Tandaan
public void createPopulatedWorld(int population)
throws EmptyWorldException, LonelyWorldException
{
   createWorld(population);
}
Ang paraan ng pagtawag ay hindi nakakakuha ng mga pagbubukod at dapat ipaalam sa iba ang tungkol sa mga ito: idinaragdag nito ang mga ito sa sarili nitong throwssugnay

2. Mahuli ang ilan sa mga pagbubukod

Hinahawakan namin ang mga pagkakamali na kaya naming hawakan. Pero yung hindi natin naiintindihan, ibinabato natin sa calling method. Para magawa ito, kailangan nating idagdag ang kanilang pangalan sa throws clause:

Code Tandaan
public void createNonEmptyWorld(int population)
throws EmptyWorldException
{
   try
   {
      createWorld(population);
   }
   catch (LonelyWorldException e)
   {
      e.printStackTrace();
   }
}
Ang tumatawag ay nakakakuha lamang ng isang naka-check na exception — LonelyWorldException. Ang iba pang pagbubukod ay dapat idagdag sa lagda nito, na nagsasaad nito pagkatapos ng throwskeyword

3. Mahuli ang lahat ng mga pagbubukod

Kung ang pamamaraan ay hindi nagtatapon ng mga pagbubukod sa paraan ng pagtawag, kung gayon ang paraan ng pagtawag ay palaging tiwala na ang lahat ay gumana nang maayos. At hindi ito makakagawa ng anumang aksyon upang ayusin ang isang pambihirang sitwasyon.

Code Tandaan
public void createAnyWorld(int population)
{
   try
   {
      createWorld(population);
   }
   catch (LonelyWorldException e)
   {
      e.printStackTrace();
   }
   catch (EmptyWorldException e)
   {
      e.printStackTrace();
   }
}
Ang lahat ng mga pagbubukod ay nakuha sa pamamaraang ito. Magtitiwala ang tumatawag na naging maayos ang lahat.


3. Pagkuha ng maraming exception

Ayaw talaga ng mga programmer na duplicate ang code. Nakaisip pa sila ng kaukulang prinsipyo ng pag-unlad — DRY : Huwag Ulitin ang Iyong Sarili. Ngunit kapag humahawak ng mga pagbubukod, may mga madalas na pagkakataon na ang isang trybloke ay sinusundan ng ilang catchmga bloke na may parehong code.

O maaaring mayroong 3 catchbloke na may parehong code at isa pang 2 catchbloke na may iba pang magkaparehong code. Ito ay isang karaniwang sitwasyon kapag ang iyong proyekto ay humahawak ng mga pagbubukod nang responsable.

Simula sa bersyon 7, sa wikang Java ay nagdagdag ng kakayahang tumukoy ng maraming uri ng mga pagbubukod sa isang catchbloke. Ito ay halos ganito:

try
{
   // Code where an exception might occur
}
catch (ExceptionType1 | ExceptionType2 | ExceptionType3 name)
{
   // Exception handling code
}

Maaari kang magkaroon ng maraming catchmga bloke hangga't gusto mo. Gayunpaman, hindi maaaring tukuyin ng isang catchbloke ang mga pagbubukod na nagmamana sa isa't isa. Sa madaling salita, hindi ka maaaring sumulat ng catch ( Exception| RuntimeExceptione), dahil ang RuntimeExceptionklase ay namamana Exception.