ব্যতিক্রম ধরা এবং নকল অবধি ছোঁয়া


155

বিশ্ববিদ্যালয়ে জাভা সম্পর্কিত প্রশ্নে কোডের এই স্নিপেট ছিল:

class MyExc1 extends Exception {}
class MyExc2 extends Exception {}
class MyExc3 extends MyExc2 {}

public class C1 {
    public static void main(String[] args) throws Exception {
        try {
            System.out.print(1);
            q();
        }
        catch (Exception i) {
            throw new MyExc2();
        }
        finally {
            System.out.print(2);
            throw new MyExc1();
        }
    }

    static void q() throws Exception {
        try {
            throw new MyExc1();
        }
        catch (Exception y) {
        }
        finally {
            System.out.print(3);
            throw new Exception();
        }
    }
}

আমাকে এর আউটপুট দিতে বলা হয়েছিল। আমি উত্তর দিয়েছি 13Exception in thread main MyExc2, তবে সঠিক উত্তরটি হচ্ছে 132Exception in thread main MyExc1। এটা কেন? আমি বুঝতে পারি না কোথায় MyExc2যায়।

উত্তর:


167

আপনার উত্তরটি পড়া এবং আপনি কীভাবে সম্ভবত এটি সামনে এসেছেন তার ভিত্তিতে, আমি বিশ্বাস করি যে আপনি "ব্যতিক্রমী অগ্রগতি" "এর" অগ্রাধিকার "বলে মনে করেন। মনে রেখ:

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

নোট করুন যে প্রযোজ্য ক্যাচ বা অবশেষে ব্লকগুলির মধ্যে রয়েছে:

যখন কোনও নতুন ব্যতিক্রম ক্যাপ ব্লকে নিক্ষেপ করা হয় তখন নতুন ব্যতিক্রমটি সেই ক্যাচের অবশেষে অবরুদ্ধ ব্লকের সাপেক্ষে যদি থাকে তবে।

এখন যখনই আপনি আঘাত করবেন তখন মনে রাখবেন কার্যকর করে ফিরুন hit throwআপনার বর্তমান ব্যতিক্রমটি ট্রেস করা বাতিল করা উচিত এবং নতুন ব্যতিক্রমটি ট্রেস করা শুরু করা উচিত।


7
Your আপনার উত্তরটি পড়ার ভিত্তিতে এবং কীভাবে আপনি সম্ভবত এটি নিয়ে এসেছেন তা দেখার ভিত্তিতে, আমি বিশ্বাস করি যে আপনি "ব্যতিক্রমী-অগ্রগতিতে" "অগ্রাধিকার" পেয়েছেন বলে মনে করেন
you

39

শেষ অবধি সম্পর্কে উইকিপিডিয়া এটাই বলে:

আরও সাধারণ একটি সম্পর্কিত ধারা (শেষ অবধি, বা নিশ্চিত হওয়া) যা ব্যতিক্রম ঘটেছে কিনা তা কার্যকর করা হয়, সাধারণত ব্যতিক্রম হ্যান্ডলিং ব্লকের মূল অংশের মধ্যে অর্জিত সংস্থানগুলি প্রকাশ করতে।

আসুন আপনার প্রোগ্রাম বিচ্ছিন্ন করা যাক।

try {
    System.out.print(1);
    q();
}

সুতরাং, 1পর্দায় আউটপুট হবে, তারপর q()বলা হয়। ইন q(), একটি ব্যতিক্রম নিক্ষেপ করা হয়। ব্যতিক্রমটি তখন ধরা পড়ে Exception yতবে কিছুই করে না। একটি পরিশেষে ধারাটি পরে কার্যকর করা হয় (এটি করতে হবে), সুতরাং, 3স্ক্রিনে মুদ্রিত হবে। কারণ (পদ্ধতিতে পরিশেষে ধারাটিতেও q()একটি ব্যতিক্রম ছুঁড়ে দেওয়া আছেq() পদ্ধতিটি পিতামাতার স্ট্যাকের ব্যতিক্রমকে পাশ করে দেয় ( throws Exceptionপদ্ধতি ঘোষণার মাধ্যমে) new Exception()নিক্ষিপ্ত হবে এবং ধরে ফেলবে catch ( Exception i ), MyExc2ব্যতিক্রম ছুঁড়ে যাবে (আপাতত ব্যতিক্রম স্ট্যাকটিতে এটি যুক্ত করুন ), তবে অবশেষেmain ব্লকের মধ্যে প্রথমে কার্যকর করা হবে।

সুতরাং,

catch ( Exception i ) {
    throw( new MyExc2() );
} 
finally {
    System.out.print(2);
    throw( new MyExc1() );
}

একজন অবশেষে দফা বলা হয় ... (মনে রাখবেন, আমরা শুধু ধরা থাকেন Exception iএবং নিক্ষিপ্তMyExc2 ) ভব, 2পর্দায় ছাপা হয় ... এবং পরে 2পর্দায় ছাপা হয়, একটি MyExc1ব্যতিক্রম ফেলে দেওয়া হয়। পদ্ধতি MyExc1দ্বারা পরিচালিত হয় public static void main(...)

আউটপুট:

"থ্রেড মাই মাইএক্সসি 1 এ 132 অনুভূতি"

প্রভাষক সঠিক! :-)

সংক্ষেপে , আপনার যদি শেষ পর্যন্ত চেষ্টা / ধরার ধারাতে থাকে তবে শেষ পর্যন্ত মৃত্যুদন্ড কার্যকর করা হবে ( ধরা পড়া ব্যতিক্রমটি ছুঁড়ে দেওয়ার আগে ব্যতিক্রম ধরা পরে )


catchযেহেতু কার্যকর q()একটি ছুড়ে ফেলে Exceptionনিজস্ব থেকে finallyব্লক।
প্যাটার তুরিক

"কিউ () তে একটি ব্যতিক্রম ছুঁড়ে দেওয়া হয়েছে তবে ব্যতিক্রমটি পুরোপুরি ছুঁড়ে ফেলার আগে একটি চূড়ান্ত ধারাটি প্রথমে কার্যকর করা হবে, সুতরাং 3 টি স্ক্রিনে মুদ্রণ করা হবে।" এর ... না, প্রথম ব্যতিক্রমটি qফাঁসির মৃত্যুদন্ড কার্যকর করা হয় খালি catchব্লক ইন q(যা এই ব্যতিক্রমটিকে গ্রাস করে), তারপরে finallyব্লকটিতে q। পরিশেষে কপি করে প্রিন্ট ব্লক বলল 3, তারপর একটি নতুন ব্যতিক্রম, যা ধন্যবাদ ছোঁড়ার qএর throws Exceptionঊর্ধ্বতন স্ট্যাক আপ পাস করা হয়েছে।
পাওয়ারলর্ড

38

শেষ পর্যন্ত ব্লক সুপারিডে ব্যতিক্রম ক্যাপ ব্লকে ব্যতিক্রম।

জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন 14 সংস্করণ থেকে উদ্ধৃত :

আর ব্লকের কারণে যদি ক্যাচ ব্লকটি হঠাৎ করে সম্পূর্ণ করে, তবে শেষ অবধি ব্লকটি কার্যকর করা হয়। তারপরে একটি পছন্দ আছে:

  • যদি অবশেষে ব্লকটি স্বাভাবিকভাবে সম্পূর্ণ হয়, তবে চেষ্টা স্টেটমেন্টটি হঠাৎ করে আর এর জন্য পূর্ণ হয়।

  • যদি অবশেষে ব্লকটি হঠাৎ করে এস এর কারণে সম্পূর্ণ হয়, তবে চেষ্টা স্টেটমেন্ট হঠাৎ করে এস এর কারণে পূর্ণ হয় (এবং কারণটি বাতিল করা হয়)।


21

চেষ্টা / ধরা ব্লক থেকে যে কোনও জায়গা থেকে ব্যতিক্রম ছুঁড়ে ফেলা হলেও অবশেষে ধারাটি কার্যকর করা হয়।

কারণ এটি সর্বশেষে কার্যকর করা হবে main এবং এটি একটি ব্যতিক্রম ছুঁড়ে দেয়, কলাররা এটি ব্যতিক্রম।

সুতরাং finallyক্লজটি কোনও কিছু ফেলে না দেয় তা নিশ্চিত করার গুরুত্ব , কারণ এটি tryব্লক থেকে ব্যতিক্রমগুলি গ্রাস করতে পারে ।


5
ট্রাই / ক্যাচ ব্লকে কোনও ব্যতিক্রম না ফেলেও এটি কার্যকর করা হবে
নান্দা

2
+1: সম্পূর্ণ স্ট্যাকটি যা ওপিটি ইতিমধ্যে বুঝতে পারে তা হ্রাস না করে সরাসরি এবং বিন্দুতে।
পাওয়ারলর্ড

9

এ একই সাথে দুটি ব্যতিক্রম methodহতে পারে না throw। এটি সর্বদা সর্বশেষ নিক্ষেপ করবে exception, যা এই ক্ষেত্রে এটি সর্বদা এক হতে পারেfinally ব্লক ।

যখন পদ্ধতি থেকে প্রথম ব্যতিক্রম q()নিক্ষেপ করা হবে, তখন এটি ধরা পড়বে এবং তারপরে অবশেষে ব্লক নিক্ষিপ্ত ব্যতিক্রম দ্বারা গ্রাস করা হবে।

q () -> নিক্ষিপ্ত new Exception -> main catch Exception -> throw new Exception -> finally একটি নতুন নিক্ষেপ করুন exception(এবং এর মধ্যে একটি catch"হারিয়ে গেছে")


3

এটি ভাবার সহজতম উপায়টি কল্পনা করা যায় যে পুরো প্রয়োগটিতে একটি পরিবর্তনশীল গ্লোবাল রয়েছে যা বর্তমান ব্যতিক্রমকে ধারণ করে।

Exception currentException = null;

প্রতিটি ব্যতিক্রম নিক্ষেপ করার সাথে সাথে "কারেন্টএক্সসেপশন" সেটাকে ব্যতিক্রম হিসাবে সেট করা হয়। যখন অ্যাপ্লিকেশনটি শেষ হয়, যদি বর্তমানের অনুগ্রহ! = বাতিল হয়, তবে রানটাইম ত্রুটিটি রিপোর্ট করে।

এছাড়াও, অবশেষে ব্লকগুলি সর্বদা পদ্ধতিটি প্রস্থান হওয়ার আগে চলে। তারপরে আপনি কোড স্নিপেটের কাছে এইটির প্রয়োজন পড়তে পারেন:

public class C1 {

    public static void main(String [] argv) throws Exception {
        try {
            System.out.print(1);
            q();

        }
        catch ( Exception i ) {
            // <-- currentException = Exception, as thrown by q()'s finally block
            throw( new MyExc2() ); // <-- currentException = MyExc2
        }
        finally {
             // <-- currentException = MyExc2, thrown from main()'s catch block
            System.out.print(2);
            throw( new MyExc1() ); // <-- currentException = MyExc1
        }

    }  // <-- At application exit, currentException = MyExc1, from main()'s finally block. Java now dumps that to the console.

    static void q() throws Exception {
        try {
            throw( new MyExc1() ); // <-- currentException = MyExc1
        }
        catch( Exception y ) {
           // <-- currentException = null, because the exception is caught and not rethrown
        }
        finally {
            System.out.print(3);
            throw( new Exception() ); // <-- currentException = Exception
        }
    }
}

অ্যাপ্লিকেশনটি যে আদেশে কার্যকর হয় তা হ'ল:

main()
{
  try
    q()
    {
      try
      catch
      finally
    }
  catch
  finally
}

1

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

চিয়ার্স।

/////////////Return dont always return///////

try{

    return "In Try";

}

finally{

    return "In Finally";

}

////////////////////////////////////////////


////////////////////////////////////////////    
while(true) { 

    try {

        return "In try";

   } 

   finally{

        break;     

    }          
}              
return "Out of try";      
///////////////////////////////////////////


///////////////////////////////////////////////////

while (true) {     

    try {            

        return "In try";    

     } 
     finally {   

         continue;  

     }                         
}
//////////////////////////////////////////////////

/////////////////Throw dont always throw/////////

try {

    throw new RuntimeException();

} 
finally {

    return "Ouuuups no throw!";

}
////////////////////////////////////////////////// 

1
class MyExc1 extends Exception {}
class MyExc2 extends Exception {}
class MyExc3 extends MyExc2 {}

public class C1 {
    public static void main(String[] args) throws Exception {
        try {
            System.out.print("TryA L1\n");
            q();
            System.out.print("TryB L1\n");
        }
        catch (Exception i) {
            System.out.print("Catch L1\n");                
        }
        finally {
            System.out.print("Finally L1\n");
            throw new MyExc1();
        }
    }

    static void q() throws Exception {
        try {
            System.out.print("TryA L2\n");
            q2();
            System.out.print("TryB L2\n");
        }
        catch (Exception y) {
            System.out.print("Catch L2\n");
            throw new MyExc2();  
        }
        finally {
            System.out.print("Finally L2\n");
            throw new Exception();
        }
    }

    static void q2() throws Exception {
        throw new MyExc1();
    }
}

ক্রম:

TryA L1
TryA L2
Catch L2
Finally L2
Catch L1
Finally L1        
Exception in thread "main" MyExc1 at C1.main(C1.java:30)

https://www.compilejava.net/


1
যদিও এই কোড স্নিপেট একটি সমাধান সহ সমাধান হতে পারে, সত্যিই আপনার পোস্টের গুণমান উন্নত করতে সহায়তা করে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, এবং সেই লোকেরা আপনার কোড পরামর্শের কারণগুলি জানেন না
রাহুল গুপ্ত

1

যুক্তিটি মুদ্রণ শেষ না হওয়া অবধি পরিষ্কার 13। তারপর নিক্ষিপ্ত ব্যতিক্রম q()ধরা হয় catch (Exception i)main()এবং new MyEx2()ফেলে দেওয়া করার জন্য প্রস্তুত। তবে ব্যতিক্রম ছোঁড়ার আগে finallyপ্রথমে ব্লকটি কার্যকর করতে হবে uted তারপরে আউটপুটটি হয়ে যায় 132এবং finallyঅন্য একটি ব্যতিক্রম ছুঁড়ে দিতে বলে new MyEx1()

যেহেতু একটি পদ্ধতি একের বেশি নিক্ষেপ করতে পারে না Exception, এটি সর্বদা সর্বশেষতম ছুঁড়ে দেয় Exception। অন্য কথায়, যদি উভয় catchএবং finallyব্লক নিক্ষেপ করার চেষ্টা করে Exception, তবে Exceptionক্যাচটি গ্রাস করা হয় এবং কেবল ব্যতিক্রমটি এর মধ্যে রয়েছেfinally ছুঁড়ে দেওয়া হবে।

সুতরাং, এই প্রোগ্রামে, ব্যতিক্রম MyEx2গিলে MyEx1ফেলে দেওয়া হয়। এই ব্যতিক্রমটি বাইরে ফেলে দেওয়া হয় main()এবং আর ধরা পড়ে না, এভাবে জেভিএম বন্ধ হয়ে যায় এবং চূড়ান্ত আউটপুট হয় 132Exception in thread main MyExc1

প্রকৃতরূপে, আপনি একটি আছে finallyএকটি try/catchদফা, একটি finallyমৃত্যুদন্ড কার্যকর করা হবে ব্যতিক্রম সংক্রামক পরে কিন্তু এর আগে কোনো ধরা ব্যতিক্রম নিক্ষেপ , এবং শুধুমাত্র সাম্প্রতিক ব্যতিক্রম শেষ নিক্ষেপ করা হবে


0

আমি মনে করি আপনাকে কেবল finallyব্লকগুলি হাঁটাতে হবে :

  1. "1" মুদ্রণ করুন।
  2. finallyমধ্যে qমুদ্রণ "3"।
  3. finallyমধ্যে mainমুদ্রণ "2"।

0

এই ধরণের পরিস্থিতি পরিচালনা করতে অর্থাৎ অবশেষে অবরুদ্ধের দ্বারা উত্থাপিত ব্যতিক্রমগুলি পরিচালনা করা। আপনি চেষ্টা অবরুদ্ধ করে শেষ অবধি অবরোধ করতে পারেন: পাইথনের নিচের উদাহরণটি দেখুন:

try:
   fh = open("testfile", "w")
   try:
      fh.write("This is my test file for exception handling!!")
   finally:
      print "Going to close the file"
      fh.close()
except IOError:
   print "Error: can\'t find file or read data"

-1

আমি মনে করি এটি সমস্যার সমাধান করে:

boolean allOk = false;
try{
  q();
  allOk = true;
} finally {
  try {
     is.close();
  } catch (Exception e) {
     if(allOk) {
       throw new SomeException(e);
     }
  }
}

3
কোন সমস্যা আপনি "সমাধান" করতে চলেছেন? আপনি পরীক্ষার প্রশ্ন মানে? ভাল এটি ইতিমধ্যে উত্তর। যদি আপনি প্রদত্ত কোডের সমস্যাটিকে বোঝাতে চান, যেহেতু এটি কেবল একটি পরীক্ষার প্রশ্ন, এটির জন্য দোষ দেওয়ার কোনও মানে নেই।
আর্থ ইঞ্জিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.