1. ব্যতিক্রমের ধরন

ব্যতিক্রমের ধরন

সমস্ত ব্যতিক্রমগুলি 4 প্রকারে বিভক্ত, যা আসলে এমন শ্রেণী যা একে অপরের উত্তরাধিকারী।

Throwableক্লাস

সব ব্যতিক্রমের জন্য বেস ক্লাস হল Throwableক্লাস। ক্লাসে Throwableএমন কোড রয়েছে যা একটি অ্যারেতে বর্তমান কল স্ট্যাক (বর্তমান পদ্ধতির স্ট্যাক ট্রেস) লেখে। আমরা একটু পরে শিখব একটি স্ট্যাক ট্রেস কি.

থ্রো অপারেটর শুধুমাত্র ক্লাস থেকে উদ্ভূত একটি বস্তু গ্রহণ করতে পারে Throwableএবং যদিও আপনি তাত্ত্বিকভাবে কোড লিখতে পারেন throw new Throwable();, কেউ সাধারণত এটি করে না। ক্লাসের মূল উদ্দেশ্য Throwableহল সকল ব্যতিক্রমের জন্য একটি একক অভিভাবক শ্রেণী থাকা।

Errorক্লাস

পরবর্তী ব্যতিক্রম ক্লাস হল Errorক্লাস, যা সরাসরি Throwableক্লাসের উত্তরাধিকারী হয়। গুরুতর সমস্যা দেখা দিলে জাভা মেশিন ক্লাসের Error(এবং এর বংশধরদের) বস্তু তৈরি করে । উদাহরণস্বরূপ, একটি হার্ডওয়্যার ত্রুটি, অপর্যাপ্ত মেমরি, ইত্যাদি।

সাধারণত, একজন প্রোগ্রামার হিসাবে, আপনি এমন পরিস্থিতিতে কিছুই করতে পারেন নাError যেখানে প্রোগ্রামে এই জাতীয় ত্রুটি (যে ধরনের জন্য একটি নিক্ষেপ করা উচিত) ঘটেছে: এই ত্রুটিগুলি খুব গুরুতর। আপনি যা করতে পারেন তা হল ব্যবহারকারীকে জানানো যে প্রোগ্রামটি ক্র্যাশ হচ্ছে এবং/অথবা প্রোগ্রাম লগে ত্রুটি সম্পর্কে সমস্ত পরিচিত তথ্য লিখুন।

Exceptionক্লাস

এবং ক্লাসগুলি হল সাধারণ ত্রুটিগুলির জন্য যা প্রচুর পদ্ধতির অপারেশনে ঘটে Exceptionপ্রতিটি নিক্ষিপ্ত ব্যতিক্রমের লক্ষ্য হল একটি ব্লক দ্বারা ধরা যা সঠিকভাবে এটি পরিচালনা করতে জানে।RuntimeExceptioncatch

যখন কোনো পদ্ধতি কোনো কারণে তার কাজ সম্পূর্ণ করতে পারে না, তখন তা অবিলম্বে উপযুক্ত প্রকারের ব্যতিক্রম ছুড়ে কলিং পদ্ধতিকে অবহিত করা উচিত।

অন্য কথায়, একটি ভেরিয়েবল সমান হলে null, পদ্ধতিটি একটি নিক্ষেপ করবে NullPointerException। যদি ভুল আর্গুমেন্ট পদ্ধতিতে পাস করা হয়, তাহলে এটি একটি নিক্ষেপ করবে InvalidArgumentException। যদি পদ্ধতিটি ঘটনাক্রমে শূন্য দ্বারা ভাগ করে তবে এটি একটি নিক্ষেপ করবে ArithmeticException

RuntimeExceptionক্লাস

RuntimeExceptionsএর একটি উপসেট Exceptions। আমরা এমনকি বলতে পারি যে RuntimeExceptionএটি সাধারণ ব্যতিক্রমগুলির একটি হালকা সংস্করণ ( Exception) — এই ধরনের ব্যতিক্রমগুলিতে কম প্রয়োজনীয়তা এবং বিধিনিষেধ আরোপ করা হয়

আপনি পরে Exceptionএবং এর মধ্যে পার্থক্য শিখবেন ।RuntimeException


2. Throws: চেক করা ব্যতিক্রম

নিক্ষেপ: চেক করা ব্যতিক্রম

সমস্ত জাভা ব্যতিক্রম 2টি বিভাগে পড়ে: চেক করা এবং আনচেক করা

সমস্ত ব্যতিক্রম যা উত্তরাধিকারসূত্রে প্রাপ্ত RuntimeExceptionবা আনচেক করা ব্যতিক্রমError হিসাবে বিবেচিত হয় । অন্য সব ব্যতিক্রম চেক করা হয় .

গুরুত্বপূর্ণ !

চেক করা ব্যতিক্রমগুলি চালু হওয়ার 20 বছর পরে, প্রায় প্রতিটি জাভা প্রোগ্রামার এটিকে একটি বাগ হিসাবে মনে করে। জনপ্রিয় আধুনিক ফ্রেমওয়ার্কগুলিতে, সমস্ত ব্যতিক্রমগুলির 95% আনচেক করা হয়। C# ভাষা, যা জাভা প্রায় অনুলিপি করেছে, চেক করা ব্যতিক্রম যোগ করেনি ।

চেক করা এবং আনচেক করা ব্যতিক্রমগুলির মধ্যে প্রধান পার্থক্য কী ?

চেক করা ব্যতিক্রমগুলিতে আরোপিত অতিরিক্ত প্রয়োজনীয়তা রয়েছে । মোটামুটিভাবে বলতে গেলে, এগুলি হল:

প্রয়োজনীয়তা 1

যদি একটি পদ্ধতি একটি চেক করা ব্যতিক্রম নিক্ষেপ করে , তবে এটি অবশ্যই তার স্বাক্ষরে ব্যতিক্রমের ধরণ নির্দেশ করবেএইভাবে, প্রতিটি পদ্ধতি যা এটিকে কল করে তা সচেতন যে এটিতে এই "অর্থপূর্ণ ব্যতিক্রম" ঘটতে পারে।

কীওয়ার্ডের পরে মেথড প্যারামিটারের পরে চেক করা ব্যতিক্রমগুলি নির্দেশ করুন ( ভুল করে কীওয়ার্ডটি ব্যবহার করবেন না )। এটা এই মত কিছু দেখায়: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);
}
পদ্ধতিটি সম্ভাব্যভাবে দুটি চেক করা ব্যতিক্রম নিক্ষেপ করে:

  • খালি বিশ্ব ব্যতিক্রম
  • 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প্রকল্পের অর্ধেক পদ্ধতির ধারাগুলি একটি নতুন চেক করা ব্যতিক্রম পায়। এবং অবশ্যই আপনার প্রকল্প পরীক্ষা দ্বারা আচ্ছাদিত, এবং এখন পরীক্ষা কম্পাইল না. এবং এখন আপনাকে আপনার পরীক্ষাগুলিতেও থ্রো ক্লজগুলি সম্পাদনা করতে হবে।

এবং তারপরে আপনার সমস্ত কোড (শত শত ফাইলের সমস্ত পরিবর্তন) অন্যান্য প্রোগ্রামারদের দ্বারা পর্যালোচনা করতে হবে। এবং এই মুহুর্তে আমরা নিজেদেরকে প্রশ্ন করি কেন আমরা প্রকল্পে এত রক্তাক্ত পরিবর্তন করেছি? কাজের দিন(গুলি?) এবং ভাঙা পরীক্ষা - সবই একটি চেক করা ব্যতিক্রম যোগ করার জন্য ?

এবং অবশ্যই, উত্তরাধিকার এবং পদ্ধতি ওভাররাইডিং সম্পর্কিত সমস্যা এখনও রয়েছে। চেক করা ব্যতিক্রম থেকে আসা সমস্যাগুলি সুবিধার চেয়ে অনেক বড়। নীচের লাইন হল যে এখন খুব কম লোকই তাদের ভালবাসে এবং খুব কম লোকই তাদের ব্যবহার করে।

তবে এখনও অনেক কোড রয়েছে (স্ট্যান্ডার্ড জাভা লাইব্রেরি কোড সহ) যাতে এই চেক করা ব্যতিক্রমগুলি রয়েছে। তাদের সাথে কি করা উচিত? আমরা তাদের উপেক্ষা করতে পারি না, এবং আমরা তাদের পরিচালনা করতে জানি না।

জাভা প্রোগ্রামাররা চেক করা ব্যতিক্রমগুলিকে মোড়ানোর প্রস্তাব করেছে 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ব্লক ব্যতিক্রমগুলি নির্দিষ্ট করতে পারে না যা একে অপরের উত্তরাধিকারী হয়। অন্য কথায়, আপনি ক্যাচ ( Exception| RuntimeExceptionই) লিখতে পারবেন না, কারণ 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.

জাভা মাল্টিথ্রেডিং কোয়েস্টে , আমরা আমাদের নিজস্ব কাস্টম ব্যতিক্রমগুলির সাথে কাজ করার জন্য গভীরভাবে ডুব দেব।