1. अपवादांचे प्रकार

अपवादांचे प्रकार

सर्व अपवाद 4 प्रकारांमध्ये विभागलेले आहेत, जे प्रत्यक्षात एकमेकांना वारसा देणारे वर्ग आहेत.

Throwableवर्ग

सर्व अपवादांसाठी मूळ वर्ग हा Throwableवर्ग आहे. वर्गामध्ये Throwableकोड असतो जो वर्तमान कॉल स्टॅक (वर्तमान पद्धतीचा स्टॅक ट्रेस) अॅरेवर लिहितो. स्टॅक ट्रेस म्हणजे काय ते आपण थोड्या वेळाने शिकू.

थ्रो ऑपरेटर केवळ क्लासमधून प्राप्त होणारी वस्तू स्वीकारू शकतो Throwable. आणि जरी तुम्ही सैद्धांतिकदृष्ट्या कोड लिहू शकता जसे की throw new Throwable();, सहसा कोणीही असे करत नाही. Throwableसर्व अपवादांसाठी एकच पालक वर्ग असणे हा वर्गाचा मुख्य उद्देश आहे.

Errorवर्ग

पुढील अपवाद वर्ग हा Errorवर्ग आहे, जो थेट Throwableवर्गाचा वारसा घेतो. जेव्हा गंभीर समस्या उद्भवतात तेव्हा Java मशीन वर्गाच्या Error(आणि त्याचे वंशज) वस्तू तयार करते . उदाहरणार्थ, हार्डवेअर खराब होणे, अपुरी मेमरी इ.

सहसा, प्रोग्रामर म्हणून, प्रोग्राममध्ये अशी त्रुटी (ज्या प्रकारासाठी फेकली पाहिजे) अशा परिस्थितीत आपण काहीही करू शकत नाही : या त्रुटी खूप गंभीर आहेत. Errorतुम्ही फक्त वापरकर्त्याला सूचित करू शकता की प्रोग्राम क्रॅश होत आहे आणि/किंवा प्रोग्राम लॉगमध्ये त्रुटीबद्दल सर्व ज्ञात माहिती लिहा.

Exceptionवर्ग

आणि वर्ग Exceptionहे RuntimeExceptionबर्‍याच पद्धतींच्या ऑपरेशनमध्ये होणाऱ्या सामान्य त्रुटींसाठी आहेत. प्रत्येक फेकलेल्या अपवादाचे उद्दिष्ट एका ब्लॉकद्वारे पकडले जाणे आहे catchज्याला ते योग्यरित्या कसे हाताळायचे हे माहित आहे.

जेव्हा एखादी पद्धत काही कारणास्तव तिचे कार्य पूर्ण करू शकत नाही, तेव्हा योग्य प्रकारचा अपवाद टाकून कॉलिंग पद्धतीला त्वरित सूचित केले पाहिजे.

दुस-या शब्दात, जर व्हेरिएबल बरोबर असेल null, तर पद्धत एक टाकेल NullPointerException. जर चुकीच्या वितर्क पद्धतीला पास केले गेले, तर ते फेकले जाईल InvalidArgumentException. जर पद्धत चुकून शून्याने भागली तर ती फेकून देईल ArithmeticException.

RuntimeExceptionवर्ग

RuntimeExceptionsचे उपसंच आहेत Exceptions. आम्ही असे म्हणू शकतो की RuntimeExceptionही सामान्य अपवादांची हलकी आवृत्ती आहे ( Exception) — अशा अपवादांवर कमी आवश्यकता आणि निर्बंध लादले जातात

Exceptionतुम्ही नंतर आणि नंतर फरक शिकाल RuntimeException.


2. Throws: तपासलेले अपवाद

थ्रो: चेक केलेले अपवाद

सर्व Java अपवाद 2 श्रेणींमध्ये येतात: चेक केलेले आणि अनचेक केलेले .

सर्व अपवाद ज्यांना वारसा मिळतो RuntimeExceptionकिंवा अनचेक केलेले अपवादError मानले जातात . इतर सर्व अपवाद तपासले आहेत .

महत्वाचे!

तपासलेले अपवाद सादर केल्यानंतर वीस वर्षांनी, जवळजवळ प्रत्येक Java प्रोग्रामर याला बग समजतो. लोकप्रिय आधुनिक फ्रेमवर्कमध्ये, सर्व अपवादांपैकी 95% अनचेक केलेले आहेत. C# भाषा, ज्याने Java जवळजवळ कॉपी केली आहे, चेक केलेले अपवाद जोडले नाहीत .

चेक केलेले आणि अनचेक केलेल्या अपवादांमधील मुख्य फरक काय आहे ?

चेक केलेल्या अपवादांवर अतिरिक्त आवश्यकता लागू केल्या आहेत . ढोबळपणे बोलायचे तर ते असे आहेत:

आवश्यकता १

जर एखादी पद्धत चेक केलेला अपवाद टाकत असेल , तर त्याने त्याच्या स्वाक्षरीमध्ये अपवादाचा प्रकार सूचित केला पाहिजे . अशाप्रकारे, हा "अर्थपूर्ण अपवाद" होऊ शकतो याची त्याला कॉल करणारी प्रत्येक पद्धत माहित आहे.

कीवर्ड नंतर पद्धत पॅरामीटर्स नंतर चेक केलेले अपवाद दर्शवा ( चुकून कीवर्ड वापरू नका ). हे असे काहीतरी दिसते:throwsthrow

type method (parameters) throws 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!");
}

उजवीकडील उदाहरणामध्ये, आमचा कोड अनचेक केलेला अपवाद टाकतो — कोणत्याही अतिरिक्त कृतीची आवश्यकता नाही. डावीकडील उदाहरणामध्ये, पद्धत चेक केलेला अपवाद टाकते, म्हणून throwsकीवर्ड अपवादाच्या प्रकारासह पद्धत स्वाक्षरीमध्ये जोडला जातो.

जर एखाद्या पद्धतीला अनेक चेक केलेले अपवाद टाकण्याची अपेक्षा असेल , तर ते सर्व throwsस्वल्पविरामाने विभक्त करून कीवर्ड नंतर निर्दिष्ट केले जावेत. ऑर्डर महत्वाची नाही. उदाहरण:

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

जर आपण एखाद्या पद्धतीला कॉल केला ज्याने त्याच्या स्वाक्षरीमध्ये अपवाद तपासले आहेत, तर आपण त्याकडे दुर्लक्ष करू शकत नाही.

catchतुम्ही प्रत्येकासाठी ब्लॉक्स जोडून किंवा तुमच्या पद्धतीच्या क्लॉजमध्ये जोडून असे सर्व अपवाद पकडले पाहिजेत.throws

जणू काही आपण म्हणत आहोत, " हे अपवाद इतके महत्त्वाचे आहेत की आपण ते पकडले पाहिजेत. आणि जर आपल्याला ते कसे हाताळायचे हे माहित नसेल, तर जो कोणी आमची पद्धत कॉल करेल त्याला सूचित केले पाहिजे की असे अपवाद त्यात येऊ शकतात.

उदाहरण:

कल्पना करा की आपण मानवांनी भरलेले जग तयार करण्यासाठी एक पद्धत लिहित आहोत. लोकांची प्रारंभिक संख्या वाद म्हणून पास केली जाते. त्यामुळे खूप कमी लोक असल्यास अपवाद जोडणे आवश्यक आहे.

पृथ्वी निर्माण करणे नोंद
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);
}
पद्धत संभाव्यतः दोन तपासलेले अपवाद टाकते:

  • EmptyWorldException
  • LonelyWorldException

ही पद्धत कॉल 3 प्रकारे हाताळली जाऊ शकते:

1. कोणतेही अपवाद पकडू नका

हे बर्याचदा केले जाते जेव्हा पद्धत योग्यरित्या परिस्थिती कशी हाताळायची हे माहित नसते.

कोड नोंद
public void createPopulatedWorld(int population)
throws EmptyWorldException, LonelyWorldException
{
   createWorld(population);
}
कॉलिंग पद्धत अपवाद पकडत नाही आणि इतरांना त्यांच्याबद्दल माहिती दिली पाहिजे: ती त्यांना स्वतःच्या कलमात throwsजोडते

2. काही अपवाद पहा

आम्ही हाताळू शकणाऱ्या त्रुटी आम्ही हाताळतो. पण जे आम्हाला समजत नाही, आम्ही त्यांना कॉलिंग पद्धतीवर टाकतो. हे करण्यासाठी, आम्हाला थ्रो क्लॉजमध्ये त्यांचे नाव जोडण्याची आवश्यकता आहे:

कोड नोंद
public void createNonEmptyWorld(int population)
throws EmptyWorldException
{
   try
   {
      createWorld(population);
   }
   catch (LonelyWorldException e)
   {
      e.printStackTrace();
   }
}
कॉलर फक्त एक चेक केलेला अपवाद पकडतो — LonelyWorldException. दुसरा अपवाद त्याच्या स्वाक्षरीमध्ये जोडला जाणे आवश्यक आहे, जो कीवर्ड नंतर सूचित throwsकरतो

3. सर्व अपवाद पहा

जर पद्धत कॉलिंग पद्धतीला अपवाद देत नसेल, तर कॉलिंग पद्धत नेहमी खात्री बाळगते की सर्वकाही चांगले कार्य करते. आणि ते अपवादात्मक परिस्थितीचे निराकरण करण्यासाठी कोणतीही कृती करण्यास अक्षम असेल.

कोड नोंद
public void createAnyWorld(int population)
{
   try
   {
      createWorld(population);
   }
   catch (LonelyWorldException e)
   {
      e.printStackTrace();
   }
   catch (EmptyWorldException e)
   {
      e.printStackTrace();
   }
}
सर्व अपवाद या पद्धतीत पकडले जातात. कॉलरला विश्वास असेल की सर्वकाही चांगले झाले आहे.


3. रॅपिंग अपवाद

तपासलेले अपवाद सैद्धांतिकदृष्ट्या छान वाटत होते, परंतु व्यवहारात ते प्रचंड निराशाजनक ठरले.

समजा तुमच्या प्रोजेक्टमध्ये एक सुपर लोकप्रिय पद्धत आहे. तुमच्या कार्यक्रमात शेकडो ठिकाणांहून बोलावले जाते. आणि तुम्ही त्यात एक नवीन चेक केलेला अपवाद जोडण्याचे ठरवता . आणि असे असू शकते की हा तपासलेला अपवाद खरोखरच महत्त्वाचा आणि इतका विशेष आहे की main()तो पकडला गेला तर काय करावे हे केवळ पद्धतीलाच माहीत आहे.

याचा अर्थ तुम्हाला तुमची सुपर पॉप्युलर पद्धत म्हणणाऱ्या प्रत्येक पद्धतीच्या क्लॉजमध्ये चेक केलेला अपवाद जोडावा लागेलthrows . तसेच throwsत्या पद्धती म्हणणाऱ्या सर्व पद्धतींच्या कलमात. आणि ज्या पद्धतींना त्या पद्धती म्हणतात.

परिणामी, throwsप्रकल्पातील अर्ध्या पद्धतींच्या कलमांना नवीन चेक केलेला अपवाद मिळतो. आणि अर्थातच तुमचा प्रकल्प चाचण्यांनी व्यापलेला आहे आणि आता चाचण्या संकलित होत नाहीत. आणि आता तुम्हाला तुमच्या चाचण्यांमधील थ्रो क्लॉज देखील संपादित करावे लागतील.

आणि मग तुमचे सर्व कोड (शेकडो फाईल्समधील सर्व बदल) इतर प्रोग्रामरद्वारे पुनरावलोकन करावे लागतील. आणि या टप्प्यावर आम्ही स्वतःला विचारतो की आम्ही प्रकल्पात इतके रक्तरंजित बदल का केले? कामाचे दिवस आणि तुटलेल्या चाचण्या - हे सर्व एक चेक केलेला अपवाद जोडण्यासाठी ?

आणि अर्थातच, वारसा आणि पद्धत अधिलिखित करण्याशी संबंधित समस्या अजूनही आहेत. तपासलेल्या अपवादांमधून आलेल्या समस्या फायद्यापेक्षा खूप मोठ्या आहेत. मुख्य गोष्ट अशी आहे की आता काही लोक त्यांच्यावर प्रेम करतात आणि काही लोक त्यांचा वापर करतात.

तथापि अजूनही बरेच कोड (मानक Java लायब्ररी कोडसह) आहेत ज्यात हे तपासलेले अपवाद आहेत. त्यांच्यासोबत काय करायचं? आम्ही त्यांच्याकडे दुर्लक्ष करू शकत नाही आणि त्यांना कसे हाताळायचे हे आम्हाला माहित नाही.

जावा प्रोग्रामरने चेक केलेले अपवाद मध्ये गुंडाळण्याचा प्रस्ताव दिला RuntimeException. दुसऱ्या शब्दांत, सर्व चेक केलेले अपवाद पकडा आणि नंतर अनचेक अपवाद तयार करा (उदाहरणार्थ, RuntimeException) आणि त्याऐवजी फेकून द्या. असे केल्याने असे दिसते:

try
{
   // Code where a checked exception might occur
}
catch(Exception exp)
{
   throw new RuntimeException(exp);
}

हा एक अतिशय सुंदर उपाय नाही, परंतु येथे काहीही गुन्हेगार नाही: अपवाद फक्त एक मध्ये भरलेला होता RuntimeException.

इच्छित असल्यास, आपण तेथून सहजपणे पुनर्प्राप्त करू शकता. उदाहरण:

कोड नोंद
try
{
   // Code where we wrap the checked exception
   // in a RuntimeException
}
catch(RuntimeException e)
{
   Throwable cause = e.getCause();
   if (cause instanceof Exception)
   {
      Exception exp = (Exception) cause;
      // Exception handling code goes here
   }
}







ऑब्जेक्टमध्ये संग्रहित अपवाद मिळवा RuntimeException. व्हेरिएबल causeकदाचित null

त्याचा प्रकार निश्चित करेल आणि त्यास चेक केलेल्या अपवाद प्रकारात रूपांतरित करेल.


4. अनेक अपवाद पकडणे

प्रोग्रामरना कोड डुप्लिकेट करणे खरोखरच आवडत नाही. त्यांनी एक संबंधित विकास तत्त्व देखील आणले: स्वतःची पुनरावृत्ती करू नका (DRY) . परंतु अपवाद हाताळताना, वारंवार असे प्रसंग येतात जेव्हा एका tryब्लॉकनंतर catchएकाच कोडसह अनेक ब्लॉक येतात.

catchकिंवा त्याच कोडसह 3 ब्लॉक आणि catchइतर समान कोडसह आणखी 2 ब्लॉक असू शकतात . जेव्हा तुमचा प्रकल्प अपवादांना जबाबदारीने हाताळतो तेव्हा ही एक मानक परिस्थिती असते .

आवृत्ती 7 पासून प्रारंभ करून, जावा भाषेत एकाच catchब्लॉकमध्ये अनेक प्रकारचे अपवाद निर्दिष्ट करण्याची क्षमता जोडली आहे. हे असे काहीतरी दिसते:

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

catchतुम्हाला हवे तितके ब्लॉक्स असू शकतात . तथापि, एकल catchब्लॉक अपवाद निर्दिष्ट करू शकत नाही जे एकमेकांना वारसा देतात. दुसऱ्या शब्दांत, तुम्ही catch ( Exception| RuntimeExceptione) लिहू शकत नाही, कारण RuntimeExceptionवर्ग वारसा घेतो Exception.



5. सानुकूल अपवाद

तुम्ही नेहमी तुमचा स्वतःचा अपवाद वर्ग तयार करू शकता. आपण फक्त एक वर्ग तयार करा जो RuntimeExceptionवर्गाचा वारसा घेतो. हे असे काहीतरी दिसेल:

class ClassName extends RuntimeException
{
}

तुम्ही OOP, इनहेरिटन्स, कन्स्ट्रक्टर आणि मेथड ओव्हरराइडिंग शिकता तेव्हा आम्ही तपशीलांवर चर्चा करू.

तथापि, तुमच्याकडे यासारखा साधा वर्ग असला (संपूर्णपणे कोडशिवाय), तरीही तुम्ही त्यावर आधारित अपवाद टाकू शकता:

कोड नोंद
class Solution
{
   public static void main(String[] args)
   {
      throw new MyException();
   }
}

class MyException extends RuntimeException
{
}




एक अनचेक फेकणे MyException.

Java मल्टीथ्रेडिंग क्वेस्टमध्ये , आम्ही आमच्या स्वतःच्या सानुकूल अपवादांसह कार्य करण्यासाठी खोलवर जाऊ.