সবশেষে জাভাতে কোনও ব্লক কার্যকর করা হয়?


2382

এই কোডটি বিবেচনা করে, আমি কি নিশ্চিত যে finallyব্লকটি সর্বদা কার্যকর করে, তা যাই হোক না কেন something()?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("I don't know if this will get printed out");
}

471
যদি এটি না হয়, probablyপরিবর্তে কীওয়ার্ডটির নামকরণ করা উচিত ।
দুপুর সিল্ক



2
কার্যকর জাভা অন্যথায় ইনফরমিট.com
বিনয় বাবু

27
@ বিনয়বাবু, ফাইনালাইজার ! = finally; চূড়ান্তকরণকারী == finalize()পদ্ধতি।
jaco0646

উত্তর:


2697

হ্যাঁ, finallyসঞ্চালনের পর বলা হবে tryবা catchকোড ব্লক।

কেবলমাত্র সময়গুলি finallyবলা হবে না:

  1. যদি আপনি প্রার্থনা System.exit()
  2. যদি আপনি প্রার্থনা Runtime.getRuntime().halt(exitStatus)
  3. যদি জেভিএম প্রথমে ক্রাশ হয়
  4. যদি জেভিএম tryবা catchব্লকের একটি সীমাহীন লুপে পৌঁছে যায় (বা কিছু অন্যান্য অবিচ্ছিন্ন, নন-টার্মিনেটিং স্টেটমেন্ট) block
  5. যদি ওএস জোর করে জেভিএম প্রক্রিয়াটি বন্ধ করে দেয়; যেমন, kill -9 <pid>ইউনিক্স-এ
  6. হোস্ট সিস্টেম মারা গেলে; উদাহরণস্বরূপ, পাওয়ার ব্যর্থতা, হার্ডওয়্যার ত্রুটি, ওএস প্যানিক, এবং সেটার
  7. যদি finallyব্লকটি ডেমন থ্রেড দ্বারা চালিত হতে চলেছে এবং অন্যান্য সমস্ত ডিমন-থ্রেড প্রস্থান করার আগে finallyডাকা হবে

44
আসলে thread.stop()অগত্যা বাধা দেয় না finallyমৃত্যুদন্ড কার্যকর হওয়া থেকে ব্লক।
পাইওটর ফাইন্ডেন 21

181
কেমন হয় আমরা বলতে যে finallyব্লক বলা হবে পরেtry ব্লক, এবং সামনে নিয়ন্ত্রণ নিম্নলিখিত বিবৃতি প্রেরণ করা হয়। এটি একটি অসীম লুপ জড়িত চেষ্টা ব্লকের সাথে সামঞ্জস্যপূর্ণ এবং অতএব অবশেষে ব্লকটি আসলে কখনই ডাকা হয় না।
আন্দ্রেজ ডয়েল

9
আরও একটি মামলা রয়েছে, যখন আমরা নেস্টেড
ট্রাই

7
এছাড়াও, ডেমন থ্রেড দ্বারা ছুঁড়ে দেওয়া ব্যতিক্রমের ক্ষেত্রে অবশেষে অবরুদ্ধটিকে বলা হয় না।
অমরিশ পান্ডে

14
@ বিনয়বাবু - এটি চূড়ান্তকরণের বিষয়ে, অবশেষে অবরুদ্ধ নয়
অ্যাভোমোহন

567

উদাহরণ কোড:

public static void main(String[] args) {
    System.out.println(Test.test());
}

public static int test() {
    try {
        return 0;
    }
    finally {
        System.out.println("finally trumps return.");
    }
}

আউটপুট:

finally trumps return. 
0

18
এফওয়াইআই: সি # তে আচরণটি অভিন্ন হিসাবে এই সত্যটি পৃথক করে যে-বিবৃতিটি finallyক্লাসে প্রতিস্থাপনের return 2;অনুমতি নেই ( সংকলক -ত্রুটি)।
আলেকজান্ডার পাচা

15
: এখানে একটি গুরুত্বপূর্ণ বিস্তারিত সচেতন হতে হয় stackoverflow.com/a/20363941/2684342
WoodenKitty

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

8
এটি সত্যই প্রমাণ করে না যে অবশেষে ট্রাম্প ফিরবে। রিটার্ন মান কলার কোড থেকে মুদ্রিত হয়। খুব বেশি প্রমাণ হতে পারে বলে মনে হয় না।
ত্রিমতব

20
দুঃখিত, তবে এটি একটি প্রমাণ যা প্রমাণ নয়। এটি কেবলমাত্র প্রমাণ হিসাবে প্রমাণ করতে পারেন যে এই উদাহরণটি সব জাভা প্ল্যাটফর্মগুলিতে সর্বদা এইভাবে আচরণ করে এবং অনুরূপ উদাহরণগুলিও সর্বদা এইভাবে আচরণ করে।
স্টিফেন সি

391

এছাড়াও, এটি খারাপ অভ্যাস হলেও, শেষ অবধি যদি কোনও রিটার্নের বিবৃতি থাকে তবে এটি নিয়মিত ব্লক থেকে অন্য কোনও রিটার্নকে ট্রাম্প করবে। এটি হল, নিম্নলিখিত ব্লকটি মিথ্যা ফিরে আসবে:

try { return true; } finally { return false; }

অবশেষে ব্লক থেকে ব্যতিক্রম ছোঁড়া একই জিনিস।


95
এটি সত্যিই খারাপ অভ্যাস is এটি কেন খারাপ তা সম্পর্কে আরও তথ্যের জন্য স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি / ৪৮৮৮৮/২ দেখুন ।
জন মেঘের

23
একমত। শেষ অবধি return within এর মধ্যে একটি রিটার্ন চেষ্টা করে ফেলে দেওয়া কোনও ব্যতিক্রম উপেক্ষা করে}}। ভয়ের!
neu242

8
@ ড্যামিকিকব্রি 7 আপনি কেন এটি আরও ভাল অনুশীলন বলে মনে করেন? এবং ফাংশন / পদ্ধতিটি বাতিল হলে কেন এটি আলাদা হওয়া উচিত?
কর্সিকা

8
একই কারণে আমি আমার সি ++ কোডগুলিতে গোটো ব্যবহার করি না। আমি মনে করি একাধিক রিটার্ন পড়া এবং এটি ডিবাগ করা আরও কঠিন করে তোলে (অবশ্যই খুব সহজ ক্ষেত্রে এটি প্রয়োগ হয় না)। আমি অনুমান করি যে এটি কেবল ব্যক্তিগত অগ্রাধিকার এবং শেষ পর্যন্ত আপনি যে কোনও পদ্ধতি ব্যবহার করে একই জিনিস অর্জন করতে পারবেন
ডেমোকিক্রি 7

16
যখন কোনও ধরণের ব্যতিক্রমী ঘটনা ঘটে তখন আমি বেশ কয়েকটি রিটার্ন ব্যবহার করি। যেমন (যদি না চালিয়ে যাওয়ার কারণ থাকে) ফিরে আসে;
iHearGeoff

257

জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন থেকে সরকারী শব্দগুলি এখানে।

14.20.2। শেষ অবধি চেষ্টা করে দেখুন-শেষ পর্যন্ত চেষ্টা করুন

একটি tryএকটি সঙ্গে বিবৃতি finallyব্লক প্রথম নির্বাহ দ্বারা মৃত্যুদন্ড কার্যকর করা হয় tryব্লক। তারপরে একটি পছন্দ আছে:

  • যদি tryব্লকের কার্য সম্পাদন স্বাভাবিকভাবে শেষ হয়, [...]
  • যদি একটি মান ভি এর tryকারণে ব্লকটির কার্যকরকরণ হঠাৎ করে সম্পূর্ণ throwহয় , [...]
  • সঞ্চালনের তাহলে tryব্লক অন্য কোন কারণে হঠাৎ সমাপ্ত আর , তারপর finallyব্লক মৃত্যুদন্ড কার্যকর করা হয়। তারপরে একটি পছন্দ আছে:
    • যদি অবশেষে ব্লকটি স্বাভাবিকভাবে সম্পূর্ণ হয়, তবে tryবিবৃতিটি হঠাৎ R এর কারণে সম্পূর্ণ হয় ।
    • যদি এসfinally কারণে কারণে ব্লকটি হঠাৎ করে সম্পূর্ণ হয় , তবে স্টেটমেন্টটি হঠাৎ করে এস কারণে ( এবং কারণ আর বাদ দেওয়া হয় ) জন্য সম্পূর্ণ হয়।try

এর স্পেসিফিকেশনটি returnপ্রকৃতপক্ষে এটিকে সুস্পষ্ট করে তোলে:

জেএলএস 14.17 ফেরতের বিবৃতি

ReturnStatement:
     return Expression(opt) ;

পদ্ধতি বা কনস্ট্রাক্টরটির চালকের কাছে নিয়ন্ত্রণ স্থানান্তর করার চেষ্টাreturn না করে একটি বিবৃতি ।Expression

একটি returnএকটি সঙ্গে বিবৃতি Expression প্রচেষ্টা পদ্ধতি এটি ধারণ করে invoker নিয়ন্ত্রণ হস্তান্তর করার; এর মানটি Expressionপদ্ধতির অনুরোধের মান হয়ে যায়।

পূর্ববর্তী বিবরণ বলুন " প্রচেষ্টা স্থানান্তর নিয়ন্ত্রণ " বদলে শুধু " স্থানান্তর নিয়ন্ত্রণ " কারণ যদি থেকে থাকে tryপদ্ধতি বা কন্সট্রাকটর যার মধ্যে বিবৃতি tryব্লক ধারণ returnবিবৃতি, যেকোনো finallyযারা ক্লজ tryবিবৃতি, যাতে দূরতম করার মৃত্যুদন্ড কার্যকর করা হবে, গভীরতম , নিয়ন্ত্রণ বা পদ্ধতিটির চালকের কাছে স্থানান্তরিত হওয়ার আগে। কোনও finallyধারাটির হঠাৎ সমাপ্তি একটি returnবিবৃতি দ্বারা শুরু করা নিয়ন্ত্রণের স্থানান্তরকে ব্যাহত করতে পারে ।


163

অন্যান্য প্রতিক্রিয়াগুলি ছাড়াও, এটি উল্লেখ করা গুরুত্বপূর্ণ যে 'অবশেষে' চেষ্টা করে কোনও ব্যতিক্রম / প্রত্যাবর্তিত মানকে ওভাররাইড করার অধিকার রয়েছে atch উদাহরণস্বরূপ, নিম্নলিখিত কোডটি 12 প্রদান করে:

public static int getMonthsInYear() {
    try {
        return 10;
    }
    finally {
        return 12;
    }
}

একইভাবে, নিম্নলিখিত পদ্ধতিটি একটি ব্যতিক্রম ছুঁড়ে না:

public static int getMonthsInYear() {
    try {
        throw new RuntimeException();
    }
    finally {
        return 12;
    }
}

যদিও নিম্নলিখিত পদ্ধতিটি এটি ফেলে দেয়:

public static int getMonthsInYear() {
    try {
        return 12;          
    }
    finally {
        throw new RuntimeException();
    }
}

63
এটি লক্ষ করা উচিত যে মাঝের কেসটি অবশেষে কারণ অবশেষে একটি ব্লকের ভিতরে রিটার্ন স্টেটমেন্ট থাকা একেবারে ভয়াবহ (এটি কোনও থ্রোয়েবলকে আড়াল করতে পারে)।
দিমিত্রিস অ্যান্ড্রু

2
কে ছাড়তে চায় নাOutOfMemoryError ? ;)
পুনরাবৃত্তিমুখী ধারণা

আমি এটি পরীক্ষা করেছি এবং এটি এ জাতীয় ত্রুটি (হুইপস!) দমন করে। আমি এটি সংকলন করার সময় এটি একটি সতর্কতাও জেনার করে (হ্যাঁ!)। এবং যদি আপনি একটি ফিরতি পরিবর্তনশীল সংজ্ঞা এবং তারপর ব্যবহার করে এটি প্রায় কাজ করতে পারেন return retVal পরেfinally ব্লক, যদিও অনুমান অবশ্যই যে আপনি অন্য কিছু ব্যতিক্রম চাপা কারণ কোড অন্যথায় জানার জন্য না।
মার্টেন বোদেউয়েস

120

আমি উপরোক্ত উদাহরণটি সামান্য পরিবর্তন দিয়ে চেষ্টা করেছি-

public static void main(final String[] args) {
    System.out.println(test());
}

public static int test() {
    int i = 0;
    try {
        i = 2;
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
    }
}

উপরের কোড আউটপুট:

অবশেষে ট্রাম্প ফিরে।
2

এটি কারণ যখন return i;মৃত্যুদন্ড কার্যকর iকরা হয় তার একটি মান 2 থাকে this এর পরে finallyব্লকটি কার্যকর করা হয় যেখানে 12 নির্ধারিত হয় iএবং তারপরে System.outকার্যকর হয়।

finallyব্লকটি কার্যকর করার পরে tryব্লকটি 12 রিটার্নের চেয়ে 2 দেয়, কারণ এই রিটার্নের বিবৃতি আবার কার্যকর হয় না।

আপনি অন্ধকার এই কোড ডিবাগ হবে তাহলে যে একটা অনুভূতি নির্বাহ পর পাবেন System.outএর finallyব্লক returnবিবৃতি tryব্লক আবার মৃত্যুদন্ড কার্যকর করা হয়। তবে এই ঘটনাটি নয়। এটি কেবল মান 2 প্রদান করে।


10
এই উদাহরণটি দুর্দান্ত। আমি মনে করি সবেমাত্র কোনও বিকাশকারী এটি জানবে।
আশাকরি

4
iআদিম না হলেও পূর্ণসংখ্যার অবজেক্ট হলে কী হবে ।
ইয়ামচা

এই মামলাটি বুঝতে আমার খুব কষ্ট হচ্ছে। docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.17 বলে যে, "একটি এক্সপ্রেশন সহ একটি রিটার্ন বিবৃতি পদ্ধতি বা ল্যাম্বডা শরীরের চালকের কাছে নিয়ন্ত্রণ স্থানান্তর করার চেষ্টা করে এটি .... যদি অভিব্যক্তিটির মূল্যায়ন স্বাভাবিকভাবে সম্পন্ন হয়, একটি মান ভি তৈরি করে .. "আমি এই বিবৃতিটি থেকে কী অনুমান করতে পারি তা হ'ল - মনে হয় যে রিটার্ন আবার ভাবের মূল্যায়ন করে না এটি একবার ভি ভ্যালু মূল্যায়ন করার পরে, তাই আমি পরিবর্তন করেছি প্রত্যাবর্তিত মানকে প্রভাবিত করে না, আমাকে সংশোধন করুন।
meexplorer

তবে আমি এ সম্পর্কিত কোনও প্রমাণ পাইনি, যেখানে এটি উল্লেখ করা হয়েছে যে রিটার্ন আবার অভিব্যক্তিটিকে মূল্যায়ন করে না।
মেক্সপোলার

1
@ মেমপ্লেজারটি কিছুটা দেরি করলেও এটি জেএলএস 14.20.2 তে ব্যাখ্যা করা হয়েছে চেষ্টা শেষ অবধি কার্যকর করা এবং শেষ পর্যন্ত চেষ্টা করুন - কিছুটা জটিল শব্দযুক্ত , 14.17। রিটার্নের বিবৃতিটি অবশ্যই পড়তে হবে
user85421

117

এখানে কেভিনের উত্তরের একটি বিবরণ দেওয়া হল । এটি জেনে রাখা জরুরী যে প্রত্যাবর্তনের জন্য প্রকাশের পূর্বে মূল্যায়ন করা হয় finally, এমনকি পরে তা ফিরে দেওয়া হলেও।

public static void main(String[] args) {
    System.out.println(Test.test());
}

public static int printX() {
    System.out.println("X");
    return 0;
}

public static int test() {
    try {
        return printX();
    }
    finally {
        System.out.println("finally trumps return... sort of");
    }
}

আউটপুট:

X
finally trumps return... sort of
0

8
জানা গুরুত্বপূর্ণ.
আমিনাদভ গ্লিক্সটাইন

জেনে রাখা ভাল, এবং পাশাপাশি উপলব্ধি করে। দেখে মনে হচ্ছে আসলে রিটার্নের মান ফিরিয়ে দেওয়াটাই পরে আসে finally। রিটার্ন মান গণনা করা ( printX()এখানে) এর আগেও আসে।
অ্যালবার্ট

সমস্ত 3 "রিটার্নিং" পয়েন্ট সহ একটি ভাল উদাহরণ!
রদিস্তো

নাঃ। উপরের কোড প্রতিস্থাপন করা উচিত System.out.println("finally trumps return... sort of");সঙ্গেSystem.out.print("finally trumps return in try"); return 42;
Pacerier

54

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

চেষ্টা ব্লকে যা ঘটেছিল তা বিবেচনা না করে অবশেষে বলা হবে ( যদি না আপনি কল করেন System.exit(int)বা জাভা ভার্চুয়াল মেশিনটি অন্য কোনও কারণে লাথি না দেয়)।


এটি একটি চরম দুর্বল উত্তর। stackoverflow.com/a/65049/715269
Gangnus

42

এটি সম্পর্কে ভাবার একটি যৌক্তিক উপায় হ'ল:

  1. অবশেষে ব্লকে রাখা কোডটি অবশ্যই চেষ্টা ব্লকের মধ্যে যা ঘটে তা কার্যকর করতে হবে
  2. সুতরাং যদি চেষ্টা ব্লকের কোড কোনও মান ফেরত দেওয়ার চেষ্টা করে বা কোনও ব্যতিক্রম ছুঁড়ে মারার চেষ্টা করে তবে অবশেষে ব্লকটি কার্যকর না হওয়া পর্যন্ত আইটেমটি 'শেল্ফের উপরে' রাখা হয়
  3. কারণ শেষ অবধি ব্লকের কোডের একটি উচ্চ অগ্রাধিকার রয়েছে (সংজ্ঞা অনুসারে) এটি যা পছন্দ করে তা ফিরিয়ে দিতে বা নিক্ষেপ করতে পারে। 'শেল্ফের উপরে' থাকা কোনও কিছু ফেলে দেওয়া হয়।
  4. এর ব্যতিক্রম কেবলমাত্র যদি ভিএমএম চেষ্টা ব্লকের সময় সম্পূর্ণ বন্ধ হয়ে যায় যেমন 'সিস্টেম.এক্সিট' দ্বারা

10
এটি কি কেবল "এটি সম্পর্কে ভাবার যৌক্তিক উপায়" বা অবশেষে ব্লকটি নির্দিষ্টকরণ অনুসারে কাজ করার উদ্দেশ্যে কীভাবে কাজ করছে? একটি সূর্যের উত্স একটি লিঙ্ক এখানে খুব আকর্ষণীয় হবে।
মাটিয়াস 26'10

21

অস্বাভাবিক প্রোগ্রাম সমাপ্তি না হলে অবশেষে সর্বদা মৃত্যুদন্ড কার্যকর করা হয় (যেমন কলিং সিস্টেম.এক্সিট (0) ..)। সুতরাং, আপনার সিসআউট মুদ্রিত হবে



18

জেভিএম ক্রাশের ফলে বা কল থেকে কল হয়ে অস্বাভাবিক প্রোগ্রামের সমাপ্তি না হওয়া অবশেষে অবরুদ্ধ ব্লকটি সর্বদা কার্যকর করা হয় System.exit(0)

সর্বোপরি, অবশেষে ব্লকের মধ্যে থেকে প্রত্যাবর্তিত কোনও মান শেষ অবধি কার্যকর করার পূর্বে প্রাপ্ত মানটিকে ওভাররাইড করে দেবে, সুতরাং শেষ অবধি চেষ্টা করার সময় সমস্ত প্রস্থান পয়েন্টগুলি পরীক্ষা করার বিষয়ে সতর্ক থাকুন।


18

না, সর্বদা একটি ব্যতিক্রম নয় // সিস্টেম.এক্সিট (0); অবশেষে অবরুদ্ধ হওয়ার আগে অবশেষে মৃত্যুদন্ড কার্যকর করা যায়।

  class A {
    public static void main(String args[]){
        DataInputStream cin = new DataInputStream(System.in);
        try{
            int i=Integer.parseInt(cin.readLine());
        }catch(ArithmeticException e){
        }catch(Exception e){
           System.exit(0);//Program terminates before executing finally block
        }finally{
            System.out.println("Won't be executed");
            System.out.println("No error");
        }
    }
}

এবং এটি হ'ল কারণগুলির মধ্যে আপনার সত্যই কখনই System.exit () বলা উচিত নয় ...
ফ্রেঞ্জ ডি

13

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

উদাহরণস্বরূপ যদি আপনার নিম্নলিখিত থাকে:

int foo() { 
    try {
        return 42;
    }
    finally {
        System.out.println("done");
    }
}

রানটাইম এরকম কিছু তৈরি করবে:

int foo() {
    int ret = 42;
    System.out.println("done");
    return 42;
}

যদি একটি অব্যক্ত ব্যতিক্রম নিক্ষেপ করা হয় তবে finallyব্লকটি চলবে এবং ব্যতিক্রমটি প্রচার চালিয়ে যাবে।


11

এটি হ'ল কারণ আপনি 12 হিসাবে i এর মান নির্ধারণ করেছেন, তবে i এর মানটি ফাংশনে ফিরিয়ে দেননি। সঠিক কোডটি নিম্নরূপ:

public static int test() {
    int i = 0;
    try {
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
        return i;
    }
}

10

কারণ আপনি অবধি কল না করা System.exit()(বা থ্রেড ক্র্যাশ না হওয়া) সবশেষে একটি অবরুদ্ধ ব্লক বলা হবে ।


10

সংক্ষিপ্তভাবে, সরকারী জাভা ডকুমেন্টেশনে ( এখানে ক্লিক করুন ) লিখিত আছে যে -

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


10

উত্তর সহজ হ্যাঁ

ইনপুট:

try{
    int divideByZeroException = 5 / 0;
} catch (Exception e){
    System.out.println("catch");
    return;    // also tried with break; in switch-case, got same output
} finally {
    System.out.println("finally");
}

আউটপুট:

catch
finally

1
উত্তর সহজ না।
ক্রিস্টোফ রাউসি

1
নিবন্ধন করুন আপনি দয়া করে ব্যাখ্যা করতে পারেন?
মিলিত

1
গৃহীত উত্তরটি পড়ুন, আসল প্রশ্নটি 'এটি কি সর্বদা কার্যকর করা হবে' সম্পর্কে এবং এটি সর্বদা হয় না। আপনার ক্ষেত্রে এটি হবে তবে এটি আসল প্রশ্নের উত্তর দেয় না এবং এমনকি বিভ্রান্তিকরও হতে পারে।
ক্রিস্টোফ রাউসি

তাহলে কোন ক্ষেত্রে এটি কার্যকর হবে?
মিলিত

অন্যান্য উত্তরে বর্ণিত সমস্ত ক্ষেত্রে 1000+ upvotes সহ স্বীকৃত উত্তর দেখুন।
ক্রিস্টোফ রাউসি

9

হ্যাঁ ডাকবে। শেষ অবধি কীওয়ার্ডটি হ'ল এটিই পুরো বিষয়। যদি চেষ্টা / ক্যাচ ব্লক থেকে ঝাঁপিয়ে পড়ে শেষ পর্যন্ত ব্লকটি এড়িয়ে যেতে পারে তবে এটি চেষ্টা / ধরার বাইরে System.out.println রাখার মতোই।


9

হ্যাঁ, অবশেষে ব্লক সর্বদা কার্যকর করা হয়। বেশিরভাগ বিকাশকারী এই ব্লকটি ক্লোজ করে ডাটাবেস সংযোগ, ফলাফলসেট অবজেক্ট, স্টেটমেন্ট অবজেক্ট এবং জাভা হাইবারনেটে লেনদেনকে রোলব্যাক করতে ব্যবহার করে।


9

সবসময় নয়

জাভা ল্যাঙ্গুএজ স্পেসিফিকেশন বর্ণনা কিভাবে try- catch- finallyএবং try- catchব্লক এ কাজ 14.20.2
এটা কোন স্থানে নির্দিষ্ট করে finallyব্লক সবসময় মৃত্যুদন্ড কার্যকর করা হয়। তবে যে সমস্ত ক্ষেত্রে try- catch- finallyএবং try- finallyব্লকগুলি সম্পূর্ণ হয় এটির ক্ষেত্রে এটি নির্দিষ্ট করে যে সমাপ্তির আগে finallyঅবশ্যই মৃত্যুদন্ড কার্যকর করা উচিত।

try {
  CODE inside the try block
}
finally {
  FIN code inside finally block
}
NEXT code executed after the try-finally block (may be in a different method).

JLS নিশ্চয়তা দেয় না FIN পর কার্যকর কোড । JLS গ্যারান্টী যে যদি কোড এবং পরবর্তী মৃত্যুদন্ড কার্যকর করা হয় তারপর FIN সবসময় পরে মৃত্যুদন্ড কার্যকর করা হবে কোড আগে পরবর্তী

জেএলএস গ্যারান্টি দেয় না যে finallyব্লকটি সর্বদা tryব্লকের পরে কার্যকর করা হয় ? কারণ এটি অসম্ভব। এটি অসম্ভব তবে সম্ভব নয় যে জেভিএম অবরুদ্ধ হবে (হত্যা, ক্রাশ, বিদ্যুৎ বন্ধ) কেবলমাত্র tryব্লক শেষ করার পরে কিন্তু কার্যকর করার আগেfinally । এটি এড়াতে জেএলএস কিছুই করতে পারে না।

সুতরাং, কোনও সফ্টওয়্যার যা তাদের যথাযথ আচরণের জন্য তাদের finallyপরে সর্বদা কার্যকর হওয়া ব্লকের উপর নির্ভর করেtry ব্লকগুলি বাগের সম্পূর্ণরূপে ।

returntryব্লকের নির্দেশাবলী এই ইস্যু থেকে অপ্রাসঙ্গিক। মৃত্যুদন্ড পর কোড ছুঁয়েছে যদি try- catch- finallyএটা নিশ্চিত করা হয় যে finallyব্লক সহ বা ছাড়া সামনে মৃত্যুদন্ড কার্যকর করা হয়েছে করবে returnভিতরে নির্দেশাবলী tryব্লক।


8

হ্যা এটা হবে. আপনার প্রয়াসে বা ক্যাচ ব্লকটিতে যা ঘটেছিল তা বিচার্য নয় যদি না অন্যথায় System.exit () বলা হয় বা জেভিএম ক্র্যাশ হয়। যদি ব্লকে (গুলি) তে কোনও রিটার্নের বিবৃতি থাকে, অবশেষে return রিটার্নের স্টেটমেন্টের পূর্বে কার্যকর করা হবে।


8

হ্যা এটা হবে. কেবলমাত্র এটি যদি না হয় তবে জেভিএম থেকে বেরিয়ে আসা বা ক্রাশ হবে


8

যোগ করা হচ্ছে @ vibhash এর উত্তর হিসাবে অন্য কোন উত্তর ব্যাখ্যা করেন কি নিচের মত একটি চপল বস্তুর ক্ষেত্রে ঘটবে।

public static void main(String[] args) {
    System.out.println(test().toString());
}

public static StringBuffer test() {
    StringBuffer s = new StringBuffer();
    try {
        s.append("sb");
        return s;
    } finally {
        s.append("updated ");
    }
}

আউটপুট হবে

sbupdated 

জাভা 1.8.162 হিসাবে, এটি আউটপুট নয়।
স্যাম

8

আমি এটি চেষ্টা করেছি, এটি একক থ্রেডেড।

public static void main(String args[]) throws Exception {
    Object obj = new Object();
    try {
        synchronized (obj) {
            obj.wait();
            System.out.println("after wait()");
        }
    } catch (Exception ignored) {
    } finally {
        System.out.println("finally");
    }
}

main Threadহবে waitরাষ্ট্র সব সময় প্রবেশ করুন অত: পর, finallyবলা হবে না ,

সুতরাং কনসোল আউটপুট হবে না print String: পরে wait()বাfinally

@ স্টেফেন সি এর সাথে সম্মত, উপরোক্ত উদাহরণটি এখানে উল্লেখ করা তৃতীয় মামলার একটি :

নিম্নলিখিত কোডে আরও কিছু এইরকম অসীম লুপ সম্ভাবনা যুক্ত করা হচ্ছে:

// import java.util.concurrent.Semaphore;

public static void main(String[] args) {
    try {
        // Thread.sleep(Long.MAX_VALUE);
        // Thread.currentThread().join();
        // new Semaphore(0).acquire();
        // while (true){}
        System.out.println("after sleep join semaphore exit infinite while loop");
    } catch (Exception ignored) {
    } finally {
        System.out.println("finally");
    }
}

কেস 2: জেভিএম যদি প্রথমে ক্রাশ হয়

import sun.misc.Unsafe;
import java.lang.reflect.Field;

public static void main(String args[]) {
    try {
        unsafeMethod();
        //Runtime.getRuntime().halt(123);
        System.out.println("After Jvm Crash!");
    } catch (Exception e) {
    } finally {
        System.out.println("finally");
    }
}

private static void unsafeMethod() throws NoSuchFieldException, IllegalAccessException {
    Field f = Unsafe.class.getDeclaredField("theUnsafe");
    f.setAccessible(true);
    Unsafe unsafe = (Unsafe) f.get(null);
    unsafe.putAddress(0, 0);
}

রেফ: আপনি কীভাবে জেভিএমকে ক্র্যাশ করবেন?

কেস।: যদি finallyব্লকটি ডেমন দ্বারা নির্বাহ করা হয় Threadএবং অন্য সমস্ত ডেমোনের Threadsবাইরে যাওয়ার আগে finallyডাকা হয়।

public static void main(String args[]) {
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                printThreads("Daemon Thread printing");
                // just to ensure this thread will live longer than main thread
                Thread.sleep(10000);
            } catch (Exception e) {
            } finally {
                System.out.println("finally");
            }
        }
    };
    Thread daemonThread = new Thread(runnable);
    daemonThread.setDaemon(Boolean.TRUE);
    daemonThread.setName("My Daemon Thread");
    daemonThread.start();
    printThreads("main Thread Printing");
}

private static synchronized void printThreads(String str) {
    System.out.println(str);
    int threadCount = 0;
    Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
    for (Thread t : threadSet) {
        if (t.getThreadGroup() == Thread.currentThread().getThreadGroup()) {
            System.out.println("Thread :" + t + ":" + "state:" + t.getState());
            ++threadCount;
        }
    }
    System.out.println("Thread count started by Main thread:" + threadCount);
    System.out.println("-------------------------------------------------");
}

আউটপুট: এটি "শেষ অবধি" মুদ্রণ করে না যা "ডেমন থ্রেড" এর "শেষ অবধি" কার্যকর করে নি

main Thread Printing  
Thread :Thread[My Daemon Thread,5,main]:state:BLOCKED  
Thread :Thread[main,5,main]:state:RUNNABLE  
Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE   
Thread count started by Main thread:3  
-------------------------------------------------  
Daemon Thread printing  
Thread :Thread[My Daemon Thread,5,main]:state:RUNNABLE  
Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE  
Thread count started by Main thread:2  
-------------------------------------------------  

Process finished with exit code 0

4
গৃহীত উত্তর দেখুন। এটি "অসীম লুপ" এর এক প্রান্তের কেস।
স্টিফেন সি

8

নিম্নলিখিত প্রোগ্রাম বিবেচনা করুন:

public class SomeTest {

    private static StringBuilder sb = new StringBuilder();

    public static void main(String args[]) {

        System.out.println(someString());
        System.out.println("---AGAIN---");
        System.out.println(someString());
        System.out.println("---PRINT THE RESULT---");
        System.out.println(sb.toString());
    }

    private static String someString() {

        try {
            sb.append("-abc-");
            return sb.toString();

        } finally {
            sb.append("xyz");
        }
    }
}

জাভা 1.8.162 হিসাবে, উপরের কোড ব্লকটি নিম্নলিখিত আউটপুট দেয়:

-abc-
---AGAIN---
-abc-xyz-abc-
---PRINT THE RESULT---
-abc-xyz-abc-xyz

এর অর্থ হল যে finallyঅবজেক্টগুলি মুক্ত করা ব্যবহার করা নিম্নলিখিত কোডগুলির মতো একটি ভাল অনুশীলন:

private static String someString() {

    StringBuilder sb = new StringBuilder();

    try {
        sb.append("abc");
        return sb.toString();

    } finally {
        sb = null; // Just an example, but you can close streams or DB connections this way.
    }
}

এটা sb.setLength(0)শেষ পর্যন্ত করা উচিত নয় ?
user7294900

sb.setLength (0) স্ট্রিংবফারে ডেটা খালি করবে। সুতরাং, sb = নাল তথ্যটিকে রেফারেন্স থেকে আলাদা করবে।
স্যাম

আউটপুটে "xyz" দু'বার মুদ্রিত হওয়া উচিত নয়? যেহেতু ফাংশনটি দু'বার বলা হয়েছিল, "অবশেষে" একবারে কেন?
ফ্রেসকো

2
এটি একটি ভাল অনুশীলন নয়। এটি অবশেষে sb = null;কেবল অনিবদ্ধ কোড যুক্ত করে অবরুদ্ধ করে । আমি বুঝতে পেরেছি যে আপনার অর্থ finallyহ'ল একটি ব্লক হ'ল ডেটাবেস সংযোগ বা এর মতো কোনও কিছুর মতো সম্পদ মুক্ত করার জন্য একটি ভাল জায়গা, তবে মনে রাখবেন যে আপনার উদাহরণটি নতুনদেরকে বিভ্রান্ত করতে পারে।
রক বোরোনট

1
@ সামিম ধন্যবাদ, আমি লাইনগুলি যুক্ত করেছি System.out.println("---AGAIN2---"); System.out.println(sb);এবং এটি এখন আরও পরিষ্কার। যেমনটি ছিল, আউটপুটটি আপনার থিসিসের বিপরীতে ছিল: p আমি আপনার উত্তরে যুক্তও করেছিলাম, তবে সম্পাদনাটি অবশ্যই একজন মডারেটর বা সেইরকম কেউ গ্রহণ করতে হবে। অন্যথায় আপনি
এগুলি

7

এটি যে কোনও ভাষায় সত্যই ... অবশেষে রিটার্নের স্টেটমেন্টের আগে সর্বদা কার্যকর করা হবে, পদ্ধতিটি যে পদ্ধতিতে ফিরে আসুক না কেন। যদি এটি না হয়, অবশেষে ব্লকের খুব বেশি অর্থ হয় না।


7

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


7

finally কার্যকর করা হবে এবং এটি নিশ্চিত।

finally নীচের ক্ষেত্রে কার্যকর করা হবে না:

মামলা 1 :

যখন আপনি নির্বাহ করছেন System.exit()

কেস 2:

যখন আপনার জেভিএম / থ্রেড ক্রাশ হয়।

কেস 3:

যখন আপনার মৃত্যুদন্ডটি ম্যানুয়ালি মধ্যে থামানো হবে।


6
  1. অবশেষে ব্লক সর্বদা কার্যকর করা হবে। সিস্টেম এবং এক্সিট ছাড়াই () বিবৃতিটি উপস্থিত না এবং অবশেষে অবশেষে ব্লকের প্রথম বিবৃতি)।
  2. যদি system.exit () প্রথম বিবৃতি হয় তবে অবশেষে ব্লকটি কার্যকর হবে না এবং শেষ পর্যন্ত ব্লক থেকে নিয়ন্ত্রণ চলে আসে। যখনই সিস্টেম.এক্সিট () স্টেটমেন্টটি অবশেষে এই স্টেটমেন্টটি কার্যকর না হওয়া অবধি অবরুদ্ধ হয়ে যায় এবং যখন সিস্টেম.exit () প্রদর্শিত হবে তখন নিয়ন্ত্রণ বাহিনীটি শেষ অবধি সম্পূর্ণরূপে বেরিয়ে আসে।

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