ক্যাচ ব্লকের ভিতরে ফেলে দেওয়া ব্যতিক্রম - তা আবার ধরা পড়বে কি?


180

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

try {
  // Do something
} catch(IOException e) {
  throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
  // Will the ApplicationException be caught here?
}

আমি সবসময় ভেবেছিলাম উত্তরটি হ'ল না, তবে এখন আমার কিছু অদ্ভুত আচরণ রয়েছে যা এটির কারণে হতে পারে। উত্তর সম্ভবত বেশিরভাগ ভাষার ক্ষেত্রে একই তবে আমি জাভাতে কাজ করছি।


2
সম্ভবত আপনি "বিজোড় আচরণ" বর্ণনা করতে পারেন?
জেফরি এল হুইলেটজ

আপনি কি নিশ্চিত যে অ্যাপ্লিকেশনএক্সসেপশন অন্য কোথাও ফেলে দেওয়া হচ্ছে না এবং এই ব্লক পর্যন্ত প্রচার করা হচ্ছে না?
sblundy

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

উত্তর:


214

না, নতুন যেহেতু throwনেই tryব্লক সরাসরি।


কোডগুলি এই জাতীয় say say ধরা (ব্যাতিকরণ) {System.err.println ("ক্যাচে ব্যতিক্রম:" + e.getClass ()) চেষ্টা করে বলুন; } ক্যাচ (আইওএক্সেপশন ই) {System.err.println ("ক্যাচ আইওএক্সেপশন:" + e.getClass ()); try এবং চেষ্টা ব্লকের কোডটি আইও ব্যতিক্রম উত্পন্ন করে, এটি কি তাত্ক্ষণিক সাধারণ ব্যতিক্রম ব্লকে যাবে বা এটি আইওএক্সেপশন ক্যাচ ব্লকে যাবে?
sofs1

4
@ user3705478 এই ধরণের ভ্রান্ত পরিস্থিতি এড়াতে কোডটি সংকলন করবে না। সাধারণভাবে, একই চেষ্টা ব্লকে আপনাকে সুপারক্লাসের ক্যাচ দেওয়ার পরে সাবক্লাসের জন্য ক্যাচ রাখার অনুমতি নেই।
ক্রিস জেস্টার-ইয়ং

ধন্যবাদ। তাই আমি একটি সংকলন সময় ত্রুটি পাবেন, তাই না? আমি বাড়িতে এলে এটি পরীক্ষা করব।
sofs1

এটি @ ব্যবহারকারী3705478 নির্ভর করে, যদি ব্লক RuntimeExceptionথেকে একটি ফেলে দেওয়া হয় তবে catchকোনও সংকলনের ত্রুটি থাকবে না।
দেব

@ অ্যান্ড্রুডন আমি ব্যবহারকারী3705478 এর প্রশ্ন সম্পর্কে এমনটি মনে করি না, বরং, যদি কোনও পিতা-মাতার ব্যতিক্রম শর্তটি সন্তানের ব্যতিক্রম ধারার আগেcatch তালিকাভুক্ত করা হয় তবে কী ঘটে । আমার উপলব্ধি হ'ল জাভা এটিকে অস্বীকার করে এবং সংকলনের সময় এটি ধরা পড়ে। catch
ক্রিস জেস্টার-ইয়ং

71

না এটি চেক করা খুব সহজ।

public class Catch {
    public static void main(String[] args) {
        try {
            throw new java.io.IOException();
        } catch (java.io.IOException exc) {
            System.err.println("In catch IOException: "+exc.getClass());
            throw new RuntimeException();
        } catch (Exception exc) {
            System.err.println("In catch Exception: "+exc.getClass());
        } finally {
            System.err.println("In finally");
        }
    }
}

মুদ্রণ করা উচিত:

আইওএক্সেপশন ধরতে: শ্রেণি java.io.IOException
অবশেষে
থ্রেড "মূল" জাভা.এলং.রুনটাইম এক্সসেপশন ব্যতিক্রম Ex
        Catch.main এ (Catch.java:8)

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

এছাড়াও লক্ষ করুন, আপনি যদি দুটি ক্যাচ ব্লকের চারপাশে অদলবদল করেন তবে এটি সংকলন করবে না। দ্বিতীয় ক্যাচটি সম্পূর্ণ অ্যাক্সেসযোগ্য হবে।

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


3
একটি এড়ানোর সর্বাধিক সুস্পষ্ট উপায় finallyহ'ল কল করা System.exit। :
ক্রিস জেস্টার-ইয়ং

3
@ ক্রিস জেসেস্টার-ইয়ং for(;;);সংক্ষিপ্ত, ভাষার মধ্যে অন্তর্ভুক্ত, পার্শ্ব-প্রতিক্রিয়াগুলির পথে খুব বেশি পরিচয় করিয়ে দেয় না এবং আমার কাছে এটি আরও স্পষ্ট।
টম হাটিন -

1
System.exitসিপিইউর সাথে বন্ধুত্বপূর্ণ! : -ও তবে হ্যাঁ, ঠিক আছে, স্পষ্টতই এটি একটি বিষয়গত মানদণ্ড। এছাড়াও, আমি আপনাকে কোনও কোড গল্ফার হতে জানি না। ;-)
ক্রিস জেস্টার-ইয়ং

28

জাভা ভাষার স্পেসিফিকেশন 14.19.1 বিভাগে বলেছেন:

যদি ভ্যালু ভি এর একটি ছোঁড়ার কারণে চেষ্টা করে ব্লকটি কার্যকর করা হঠাৎ করেই সম্পূর্ণ হয়, তবে একটি পছন্দ আছে:

  • ট্রাই স্টেটমেন্টের কোনও ক্যাচ ক্লজের প্যারামিটারে রান-টাইম টাইপের ভি যদি নির্ধারিত হয়, তবে এই ধরণের প্রথম (বামতম) বাছাই করা হয়েছে catch নির্বাচিত ক্যাচ ক্লজের প্যারামিটারে V মান নির্ধারিত হয় এবং সেই ক্যাচ ক্লজের ব্লক কার্যকর করা হয়। যদি সেই ব্লকটি স্বাভাবিকভাবে সম্পূর্ণ হয়, তবে চেষ্টা স্টেটমেন্টটি স্বাভাবিকভাবে সম্পূর্ণ হয়; যদি সেই ব্লকটি কোনও কারণে হঠাৎ করেই সম্পূর্ণ হয়, তবে চেষ্টা স্টেটমেন্টটি একই কারণে হঠাৎ করেই সম্পূর্ণ হয়।

তথ্যসূত্র: http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#24134

অন্য কথায়, প্রথম এনকোলেজিং ক্যাচ যা ব্যতিক্রমটিকে পরিচালনা করতে পারে এবং যদি কোনও ব্যতিক্রম যদি সেই ক্যাচ থেকে ছুঁড়ে ফেলা হয় তবে এটি মূল চেষ্টা করার জন্য অন্য কোনও ক্যাচের সুযোগে নেই, তাই তারা এটি হ্যান্ডেল করার চেষ্টা করবে না।

সম্পর্কিত এবং বিভ্রান্ত করার মতো একটি বিষয় হ'ল একটি চেষ্টা- [ধরুন] - শেষ অবধি কাঠামোতে, শেষ অবধি একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে এবং যদি তাই হয়, চেষ্টা বা ক্যাচ ব্লকের দ্বারা ছুঁড়ে দেওয়া কোনও ব্যতিক্রম হারিয়ে যায়। আপনি এটি প্রথমবার দেখলে তা বিভ্রান্তিকর হতে পারে।


কেবল এটি যুক্ত করতে চেয়েছিলেন জাভা trysince-এর পরে আপনি যে -সংস্থানসমূহ ব্যবহার করে তা এড়াতে পারেন । তারপরে, tryএবং যদি finallyউভয়ই নিক্ষেপ করে finallyতবে এটি চাপা দেওয়া হয়, তবে এটির ব্যতিক্রম ছাড়াও যুক্ত হয় try। যদি catchএটিও ছুঁড়ে যায় তবে আপনি ভাগ্য নন, যদি না আপনি নিজেকে 'অ্যাডসপ্রেসড' এর মাধ্যমে পরিচালনা করেন এবং tryব্যতিক্রমটি না যোগ করেন - তবে আপনার তিনটিই থাকবে।
এলএএফকে বলছে মনিকা পুনরায় ইনস্টল করুন 16'15

6

আপনি যদি ক্যাচ ব্লক থেকে একটি ব্যতিক্রম ছুঁড়তে চান তবে আপনাকে অবশ্যই আপনার পদ্ধতি / শ্রেণি / ইত্যাদি অবহিত করতে হবে। এটি যে ব্যতিক্রম নিক্ষেপ করা প্রয়োজন। তাই ভালো:

public void doStuff() throws MyException {
    try {
        //Stuff
    } catch(StuffException e) {
        throw new MyException();
    }
}

এবং এখন আপনার সংকলক আপনাকে চিত্কার করবে না :)


4

না - ক্রিস জেসেস্টার-ইয়ং যেমন বলেছিলেন, এটিকে পরবর্তী শ্রেণিবিন্যাসের দিকে ছুঁড়ে দেওয়া হবে।


2

উপরে যেমন বলা হয়েছে ...
আমি যুক্ত করব যে কি হচ্ছে তা দেখতে যদি আপনার সমস্যা হয় তবে আপনি যদি ডিবাগারে সমস্যাটি পুনরায় উত্পাদন করতে না পারেন তবে নতুন ব্যতিক্রমটি পুনরায় ছোঁড়ার আগে আপনি একটি ট্রেস যুক্ত করতে পারেন (ভাল পুরানো সিস্টেমের সাথে) .out.println আরও খারাপ, log4j এর মতো একটি ভাল লগ সিস্টেম সহ)।


2

এটি দ্বিতীয় ক্যাচ ব্লকের দ্বারা ধরা পড়বে না। প্রতিটি ব্যতিক্রম কেবল একবার চেষ্টা ব্লকের অভ্যন্তরে ধরা পড়ে। আপনি বাসা চেষ্টা করতে পারেন (এটি সাধারণত একটি ভাল ধারণা নয়):

try {
    doSomething();
} catch (IOException) {
   try {
       doSomething();
   } catch (IOException e) {
       throw new ApplicationException("Failed twice at doSomething" +
       e.toString());
   }          
} catch (Exception e) {
}

আমি একটি অনুরূপ কোড লিখেছি। তবে আমি বিশ্বাসী নই। আমি আমার ক্যাচ ব্লকে একটি থ্রেড.স্লিপ () কল করতে চাই। তবে থ্রেড.স্লিপ নিজেই একটি বাধা-অনুভূতি ছোঁড়ে। আপনি নিজের উদাহরণে যেমন দেখিয়েছেন তা কি ঠিক (সেরা অনুশীলন) করা উচিত?
riroo

1

না, যেহেতু ক্যাচগুলি সমস্ত একই চেষ্টা ব্লককে বোঝায়, তাই ক্যাচ ব্লকের মধ্যে থেকে ছুড়ে ফেলা একটি বেষ্টন চেষ্টা ব্লক দ্বারা ধরা পড়বে (সম্ভবত এটি পদ্ধতিতে এটি বলা হয়)


-4

পুরানো পোস্ট তবে "ই" ভেরিয়েবলটি অবশ্যই অনন্য হতে হবে:

try {
  // Do something
} catch(IOException ioE) {
  throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
  // Will the ApplicationException be caught here?
}

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