CodeGym /Java Blog /এলোমেলো /ব্যতিক্রম: ধরা এবং পরিচালনা
John Squirrels
লেভেল 41
San Francisco

ব্যতিক্রম: ধরা এবং পরিচালনা

এলোমেলো দলে প্রকাশিত
ওহে! আমি এটি উল্লেখ করতে ঘৃণা করি, তবে প্রোগ্রামারের কাজের একটি বিশাল অংশ ত্রুটির সাথে মোকাবিলা করছে। প্রায়শই, তার নিজের। দেখা যাচ্ছে যে এমন কোন মানুষ নেই যারা ভুল করে না। এবং এই ধরনের কোন প্রোগ্রাম হয় না. ব্যতিক্রম: ধরা এবং পরিচালনা - 1 অবশ্যই, একটি ত্রুটি মোকাবেলা করার সময়, প্রধান জিনিস তার কারণ বুঝতে হয়. এবং অনেক কিছু একটি প্রোগ্রামে বাগ হতে পারে. এক পর্যায়ে, জাভার নির্মাতারা নিজেদেরকে জিজ্ঞাসা করেছিলেন যে সম্ভবত প্রোগ্রামিং ত্রুটিগুলির সাথে কী করা উচিত? এগুলিকে সম্পূর্ণরূপে এড়িয়ে যাওয়া বাস্তবসম্মত নয়, প্রোগ্রামাররা এমন জিনিস লিখতে সক্ষম যা আপনি কল্পনাও করতে পারবেন না। :) সুতরাং, আমাদের ভাষাকে ত্রুটির সাথে কাজ করার জন্য একটি প্রক্রিয়া দিতে হবে। অন্য কথায়, যদি আপনার প্রোগ্রামে কোনো ত্রুটি থাকে, তাহলে পরবর্তীতে কী করতে হবে তার জন্য আপনার কিছু ধরণের স্ক্রিপ্টের প্রয়োজন। একটি ত্রুটি ঘটলে একটি প্রোগ্রাম ঠিক কি করা উচিত? আজ আমরা এই প্রক্রিয়াটির সাথে পরিচিত হব। এটিকে " জাভাতে ব্যতিক্রম " বলা হয়।

একটি ব্যতিক্রম কি?

একটি ব্যতিক্রম হল একটি ব্যতিক্রমী, অপরিকল্পিত পরিস্থিতি যা একটি প্রোগ্রাম চলাকালীন ঘটে। অনেক ব্যতিক্রম আছে। উদাহরণস্বরূপ, আপনি কোড লিখেছেন যা একটি ফাইল থেকে পাঠ্য পড়ে এবং প্রথম লাইনটি প্রদর্শন করে।

public class Main {

   public static void main(String[] args) throws IOException {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));
       String firstString = reader.readLine();
       System.out.println(firstString);
   }
}
কিন্তু এমন কোনো ফাইল না থাকলে কী হবে! প্রোগ্রামটি একটি ব্যতিক্রম তৈরি করবে: FileNotFoundException. আউটপুট: থ্রেড "main" java.io.FileNotFoundException-এ ব্যতিক্রম: C:\Users\Username\Desktop\test.txt (সিস্টেমটি নির্দিষ্ট পথ খুঁজে পায় না) জাভাতে, প্রতিটি ব্যতিক্রম একটি পৃথক শ্রেণী দ্বারা প্রতিনিধিত্ব করা হয়। এই সমস্ত ব্যতিক্রম শ্রেণী একটি সাধারণ "পূর্বপুরুষ" - Throwableপিতামাতার শ্রেণী থেকে উদ্ভূত। একটি ব্যতিক্রম শ্রেণীর নাম সাধারণত সংক্ষিপ্তভাবে প্রতিফলিত করে কেন ব্যতিক্রম ঘটেছে:
  • FileNotFoundException(ফাইলটি পাওয়া যায়নি)

  • ArithmeticException(একটি গাণিতিক অপারেশন করার সময় একটি ব্যতিক্রম ঘটেছে)

  • ArrayIndexOutOfBoundsException(সূচকটি অ্যারের সীমার বাইরে)। উদাহরণস্বরূপ, এই ব্যতিক্রমটি ঘটে যদি আপনি একটি অ্যারের অবস্থান 23 প্রদর্শন করার চেষ্টা করেন যেখানে শুধুমাত্র 10টি উপাদান রয়েছে।
সব মিলিয়ে জাভাতে এরকম প্রায় 400 টি ক্লাস আছে! এত কেন? প্রোগ্রামারদের সাথে কাজ করার জন্য তাদের আরও সুবিধাজনক করতে। এটি কল্পনা করুন: আপনি একটি প্রোগ্রাম লেখেন, এবং এটি চালানোর সময় এটি একটি ব্যতিক্রম তৈরি করে যা এইরকম দেখায়:

Exception in thread "main"
উহহহহ. :/ যে খুব সাহায্য করে না. ত্রুটিটির অর্থ কী বা এটি কোথা থেকে এসেছে তা পরিষ্কার নয়। এখানে কোন সহায়ক তথ্য নেই. কিন্তু জাভাতে ব্যতিক্রম ক্লাসের বিশাল বৈচিত্র্য প্রোগ্রামারকে সবচেয়ে গুরুত্বপূর্ণ বিষয় দেয়: ত্রুটির ধরন এবং এর সম্ভাব্য কারণ (শ্রেণীর নামে এম্বেড করা)। এটা দেখতে একেবারে অন্য জিনিস

Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (The system cannot find the specified path)
সমস্যাটি কী হতে পারে এবং সমস্যা সমাধানের জন্য কোথায় খনন শুরু করতে হবে তা অবিলম্বে পরিষ্কার! ব্যতিক্রম, যে কোন শ্রেণীর উদাহরণের মত, বস্তু।

ব্যতিক্রমগুলি ধরা এবং পরিচালনা করা

জাভাতে ব্যতিক্রমগুলির সাথে কাজ করার জন্য কোডের বিশেষ ব্লক রয়েছে: try, catchএবং finally. ব্যতিক্রম: ধরা এবং পরিচালনা - 2 কোড যেখানে প্রোগ্রামার বিশ্বাস করে যে একটি ব্যতিক্রম ঘটতে পারে ব্লকে স্থাপন করা হয় tryতার মানে এই নয় যে এখানে ব্যতিক্রম ঘটবে। এর মানে হল যে এটি এখানে ঘটতে পারে, এবং প্রোগ্রামার এই সম্ভাবনা সম্পর্কে সচেতন। আপনি যে ধরনের ত্রুটি ঘটতে আশা করছেন তা ব্লকে স্থাপন করা হয়েছে catch। এটিতে এমন সমস্ত কোড রয়েছে যা একটি ব্যতিক্রম ঘটলে কার্যকর করা উচিত। এখানে একটি উদাহরণ:

public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {

       System.out.println("Error! File not found!");
   }
}
আউটপুট: ত্রুটি! ফাইল পাওয়া যায়নি! আমরা আমাদের কোড দুটি ব্লকে রাখি। প্রথম ব্লকে, আমরা অনুমান করি যে একটি "ফাইল পাওয়া যায়নি" ত্রুটি ঘটতে পারে৷ এই tryব্লক. দ্বিতীয়টিতে, আমরা প্রোগ্রামটিকে বলি যে কোনও ত্রুটি দেখা দিলে কী করতে হবে। এবং নির্দিষ্ট ত্রুটির ধরন: FileNotFoundException. যদি আমরা ব্লকের বন্ধনীতে একটি ভিন্ন ব্যতিক্রম ক্লাস রাখি catch, তাহলে FileNotFoundExceptionধরা পড়বে না।

public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));
       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (ArithmeticException e) {

       System.out.println("Error! File not found!");
   }
}
আউটপুট: থ্রেড "main" java.io.FileNotFoundException-এ ব্যতিক্রম: C:\Users\Username\Desktop\test.txt (সিস্টেমটি নির্দিষ্ট পথ খুঁজে পায় না) ব্লকের কোডটি catchচলেনি, কারণ আমরা "কনফিগার করেছি" এই ব্লকটি ধরার জন্য ArithmeticException, এবং ব্লকের কোডটি tryএকটি ভিন্ন ধরনের ছুড়ে দিয়েছে FileNotFoundException:। আমরা পরিচালনা করার জন্য কোনো কোড লিখিনি FileNotFoundException, তাই প্রোগ্রামটি ডিফল্ট তথ্য প্রদর্শন করে FileNotFoundException। এখানে আপনাকে তিনটি বিষয়ে মনোযোগ দিতে হবে। এক নম্বর. ব্লকের কোনো লাইনে একবার ব্যতিক্রম ঘটলে try, অনুসরণকারী কোডটি কার্যকর করা হবে না। প্রোগ্রামের নির্বাহ অবিলম্বে ব্লকে "জাম্প" catch। উদাহরণ স্বরূপ:

public static void main(String[] args) {
   try {
       System.out.println("Divide by zero");
       System.out.println(366/0);// This line of code will throw an exception

       System.out.println("This");
       System.out.println("code");
       System.out.println("will not");
       System.out.println("be");
       System.out.println("executed!");

   } catch (ArithmeticException e) {

       System.out.println("The program jumped to the catch block!");
       System.out.println("Error! You can't divide by zero!");
   }
}
আউটপুট: শূন্য দিয়ে ভাগ করুন প্রোগ্রামটি ক্যাচ ব্লকে লাফিয়ে উঠল! ত্রুটি! আপনি শূন্য দিয়ে ভাগ করতে পারবেন না! ব্লকের দ্বিতীয় লাইনে try, আমরা 0 দ্বারা ভাগ করার চেষ্টা করি, যার ফলে একটি ArithmeticException. ফলস্বরূপ, ব্লকের 3-9 লাইনগুলি tryকার্যকর করা হবে না। আমরা বলেছি, প্রোগ্রাম অবিলম্বে catchব্লক নির্বাহ শুরু হয়. নাম্বার দুই. catchবেশ কয়েকটি ব্লক থাকতে পারে । যদি ব্লকের কোডটি tryএকটি নয়, তবে বিভিন্ন ধরণের ব্যতিক্রমগুলি ফেলে দিতে পারে, আপনি catchতাদের প্রতিটির জন্য একটি ব্লক লিখতে পারেন।

public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       System.out.println(366/0);
       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
      
       System.out.println("Error! File not found!");
      
   } catch (ArithmeticException e) {

       System.out.println("Error! Division by 0!");
      
   }
}
এই উদাহরণে, আমরা দুটি catchব্লক লিখেছি। যদি একটি ব্লকে FileNotFoundExceptionঘটে try, তবে প্রথম catchব্লকটি কার্যকর করা হবে। যদি একটি ArithmeticExceptionঘটে, দ্বিতীয় ব্লকটি কার্যকর করা হবে। catchআপনি চাইলে 50টি ব্লক লিখতে পারেন । অবশ্যই, 50টি ভিন্ন ধরণের ব্যতিক্রম ফেলতে পারে এমন কোড না লেখাই ভাল। :) তৃতীয়। আপনি কিভাবে জানেন যে কোন ব্যতিক্রমগুলি আপনার কোড নিক্ষেপ করতে পারে? ঠিক আছে, আপনি তাদের কিছু অনুমান করতে সক্ষম হতে পারেন, কিন্তু আপনার পক্ষে সবকিছু আপনার মাথায় রাখা অসম্ভব। জাভা কম্পাইলার তাই সবচেয়ে সাধারণ ব্যতিক্রম এবং সেগুলি ঘটতে পারে এমন পরিস্থিতিতে জানে। উদাহরণ স্বরূপ, আপনি যদি এমন কোড লেখেন যা কম্পাইলার জানে দুই ধরনের ব্যতিক্রম হতে পারে, আপনার কোড কম্পাইল করা হবে না যতক্ষণ না আপনি সেগুলি পরিচালনা করেন। আমরা নীচে এই উদাহরণ দেখতে পাবেন. এখন ব্যতিক্রম হ্যান্ডলিং সম্পর্কে কিছু শব্দ। ব্যতিক্রমগুলি পরিচালনা করার 2টি উপায় রয়েছে। আমরা ইতিমধ্যেই প্রথমটির মুখোমুখি হয়েছি: পদ্ধতিটি একটি catch()ব্লকে ব্যতিক্রমটি নিজেই পরিচালনা করতে পারে। একটি দ্বিতীয় বিকল্প আছে: পদ্ধতিটি কল স্ট্যাকের উপরে ব্যতিক্রমটিকে পুনরায় নিক্ষেপ করতে পারে। ওটার মানে কি? উদাহরণস্বরূপ, আমাদের কাছে একই printFirstString()পদ্ধতির একটি ক্লাস রয়েছে, যা একটি ফাইল পড়ে এবং এর প্রথম লাইন প্রদর্শন করে:

public static void printFirstString(String filePath) {

   BufferedReader reader = new BufferedReader(new FileReader(filePath));
   String firstString = reader.readLine();
   System.out.println(firstString);
}
বর্তমানে, আমাদের কোডটি কম্পাইল করে না, কারণ এটিতে অব্যবহিত ব্যতিক্রম রয়েছে। লাইন 1 এ, আপনি ফাইলের পাথ নির্দিষ্ট করুন। কম্পাইলার জানে যে এই ধরনের কোড সহজেই একটি তৈরি করতে পারে FileNotFoundException। 3 লাইনে, আপনি ফাইল থেকে পাঠ্যটি পড়েন। IOExceptionএই প্রক্রিয়াটি সহজেই একটি (ইনপুট/আউটপুট ত্রুটি) হতে পারে । এখন কম্পাইলার আপনাকে বলছে, "দোস্ত, আমি এই কোডটি অনুমোদন করব না এবং আমি এটি কম্পাইল করব না যতক্ষণ না আপনি আমাকে বলেন যে এই ব্যতিক্রমগুলির মধ্যে একটি ঘটলে আমার কী করা উচিত৷ এবং সেগুলি অবশ্যই আপনার লেখা কোডের উপর ভিত্তি করে ঘটতে পারে। !" এটি কাছাকাছি পেতে কোন উপায় নেই: আপনি উভয় হ্যান্ডেল করতে হবে! আমরা ইতিমধ্যে প্রথম ব্যতিক্রম হ্যান্ডলিং পদ্ধতি সম্পর্কে জানি: আমাদের কোডটি একটি tryব্লকে রাখতে হবে এবং দুটি catchব্লক যুক্ত করতে হবে:

public static void printFirstString(String filePath) {

   try {
       BufferedReader reader = new BufferedReader(new FileReader(filePath));
       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
       System.out.println("Error, file not found!");
       e.printStackTrace();
   } catch (IOException e) {
       System.out.println("File input/output error!");
       e.printStackTrace();
   }
}
কিন্তু এই একমাত্র বিকল্প নয়। আমরা পদ্ধতির ভিতরে ত্রুটি-হ্যান্ডলিং কোড লেখার পরিবর্তে ব্যতিক্রমটিকে উচ্চতর নিক্ষেপ করতে পারি। throwsএটি পদ্ধতি ঘোষণায় কীওয়ার্ড ব্যবহার করে করা হয় :

public static void printFirstString(String filePath) throws FileNotFoundException, IOException {
   BufferedReader reader = new BufferedReader(new FileReader(filePath));
   String firstString = reader.readLine();
   System.out.println(firstString);
}
কীওয়ার্ডের পরে throws, আমরা পদ্ধতিটি নিক্ষেপ করতে পারে এমন সমস্ত ধরণের ব্যতিক্রমগুলির একটি কমা দ্বারা পৃথক করা তালিকা নির্দেশ করে। কেন? printFirstString()এখন, যদি কেউ প্রোগ্রামে পদ্ধতিটি কল করতে চায় , তবে তাকে (আপনি না) ব্যতিক্রম হ্যান্ডলিং বাস্তবায়ন করতে হবে। উদাহরণস্বরূপ, ধরুন যে প্রোগ্রামের অন্য কোথাও আপনার একজন সহকর্মী একটি পদ্ধতি লিখেছেন যা আপনার printFirstString()পদ্ধতিকে কল করে:

public static void yourColleagueMethod() {

   // Your colleague's method does something

   //...and then calls your printFirstString() method with the file it needs
   printFirstString("C:\\Users\\Henry\\Desktop\\testFile.txt");
}
আমরা একটি ত্রুটি পেতে! এই কোড কম্পাইল করা হবে না! আমরা পদ্ধতিতে ব্যতিক্রম-হ্যান্ডলিং কোড লিখিনি printFirstString()ফলস্বরূপ, এই কাজটি এখন যারা পদ্ধতি ব্যবহার করে তাদের কাঁধে বর্তায়। অন্য কথায়, methodWrittenByYourColleague()পদ্ধতিতে এখন একই 2টি বিকল্প রয়েছে: try-catchউভয় ব্যতিক্রমগুলি পরিচালনা করার জন্য এটিকে অবশ্যই একটি ব্লক ব্যবহার করতে হবে, অথবা তাদের পুনরায় নিক্ষেপ করতে হবে।

public static void yourColleagueMethod() throws FileNotFoundException, IOException {
   // The method does something

   //...and then calls your printFirstString() method with the file it needs
   printFirstString("C:\\Users\\Henry\\Desktop\\testFile.txt");
}
দ্বিতীয় ক্ষেত্রে, কল স্ট্যাকের পরবর্তী পদ্ধতিটি - যেটি কল করছে methodWrittenByYourColleague()-কে ব্যতিক্রমগুলি পরিচালনা করতে হবে৷ এই কারণেই আমরা এটিকে বলি "ব্যতিক্রম ছুঁড়ে দেওয়া বা পাস করা"। আপনি কিওয়ার্ড ব্যবহার করে ব্যতিক্রমগুলিকে উপরের দিকে নিক্ষেপ করলে throws, আপনার কোড কম্পাইল হবে। এই মুহুর্তে, কম্পাইলার বলে মনে হচ্ছে, "ঠিক আছে, ঠিক আছে। আপনার কোডে একগুচ্ছ সম্ভাব্য ব্যতিক্রম রয়েছে, কিন্তু আমি এটি কম্পাইল করব। কিন্তু আমরা এই কথোপকথনে ফিরে যাব!" এবং যখন আপনি কোনো পদ্ধতিতে কল করেন যেটিতে অব্যবহিত ব্যতিক্রম রয়েছে, তখন কম্পাইলার তার প্রতিশ্রুতি পূরণ করে এবং সেগুলি সম্পর্কে আপনাকে আবার মনে করিয়ে দেয়। অবশেষে, আমরা ব্লক সম্পর্কে কথা বলব finally(শ্লেষের জন্য দুঃখিত)। try-catch-finallyএটি ব্যতিক্রম হ্যান্ডলিং triumvirate এর শেষ অংশ ।.

public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
       System.out.println("Error! File not found!");
       e.printStackTrace();
   } finally {
       System.out.println ("And here's the finally block!");
   }
}
এই উদাহরণে, ব্লকের ভিতরের কোড finallyউভয় ক্ষেত্রেই কার্যকর করা হবে। যদি ব্লকের কোডটি tryকোনো ব্যতিক্রম ছাড়াই সম্পূর্ণভাবে চালানো হয়, তাহলে finallyব্লকটি শেষ পর্যন্ত চলবে। যদি ব্লকের ভিতরের কোডটি tryএকটি ব্যতিক্রম দ্বারা বাধাপ্রাপ্ত হয় এবং প্রোগ্রামটি ব্লকে চলে যায় catch, তবে ব্লকটি ব্লকের finallyভিতরের কোডের পরেও চলবে । কেন এই প্রয়োজন? এর প্রধান উদ্দেশ্য হল বাধ্যতামূলক কোড চালানো: কোড যা পরিস্থিতি নির্বিশেষে সম্পাদন করা আবশ্যক। উদাহরণস্বরূপ, এটি প্রায়শই প্রোগ্রাম দ্বারা ব্যবহৃত কিছু সংস্থান মুক্ত করে। আমাদের কোডে, আমরা ফাইল থেকে তথ্য পড়ার জন্য একটি স্ট্রীম খুলি এবং এটি বস্তুতে প্রেরণ করি । catchBufferedReaderআমরা আমাদের পাঠক বন্ধ এবং সম্পদ ছেড়ে দিতে হবে. এটি অবশ্যই করা উচিত যাই হোক না কেন-যখন প্রোগ্রাম এটির মতো কাজ করে এবং কখন এটি একটি ব্যতিক্রম ছুঁড়ে দেয়। ব্লকটি finallyএটি করার জন্য একটি খুব সুবিধাজনক জায়গা:

public static void main(String[] args) throws IOException {

   BufferedReader reader = null;
   try {
       reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
       e.printStackTrace();
   } finally {
       System.out.println ("And here's the finally block!");
       if (reader != null) {
           reader.close();
       }
   }
}
এখন আমরা নিশ্চিত যে আমরা সংস্থানগুলির যত্ন নেব, প্রোগ্রামটি চলাকালীন যা ঘটুক না কেন। :) ব্যতিক্রম সম্পর্কে আপনার জানার প্রয়োজন শুধু এটাই নয়। ত্রুটি হ্যান্ডলিং প্রোগ্রামিং একটি সুপার গুরুত্বপূর্ণ বিষয়. অনেক নিবন্ধ এটি নিবেদিত হয়. পরবর্তী পাঠে, আমরা খুঁজে বের করব কী ধরনের ব্যতিক্রম আছে এবং কীভাবে আপনার নিজের ব্যতিক্রম তৈরি করতে হয়। :) দেখা হবে তাহলে!
মন্তব্য
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION