अप्राप्य चकर्णौरिसं अपवाद


596

क्या जावा में कोड का एक स्निपेट बनाना संभव है जो काल्पनिक java.lang.ChuckNorrisExceptionअस्थिर बना देगा ?

मन में आए विचार उदाहरण इंटरसेप्टर या पहलू-उन्मुख प्रोग्रामिंग के लिए उपयोग कर रहे हैं ।



2
उपलब्ध कराए गए लिंक @jschoen से सुझाव का उपयोग करते हुए (बाइट कोड वेरिफ़ायर को अक्षम करें) आप कुछ फेंक सकते हैं जो कि थ्रेडेबल का विस्तार नहीं करता है! नीचे मेरे उत्तर में वर्णित है।
जटालबॉर्न

4
Aioobe के उत्तर का यह अंश इस सवाल को आगे बढ़ाता है कि @jschoen काफी अच्छी तरह से जुड़ा हुआ है: "Ie, आपके प्रश्न की व्याख्या 'यदि कोई JVM विनिर्देशन से विचलित करता है, तो क्या यह प्राइमिटिव्स को फेंकने जैसा अजीब सामान कर सकता है" और उत्तर निश्चित रूप से है। हाँ।"
दान अग्नि

2
@ मोम - क्या आप इसके लिए व्यावहारिक उपयोगों पर विस्तार से बता सकते हैं?
विनीत भाटिया

3
कैसे एक अपवाद के बारे में है कि खुद पर पुनर्विचार finalize()?
रेयान

जवाबों:


314

मैंने यह कोशिश नहीं की है, इसलिए मुझे नहीं पता कि जेवीएम इस तरह से कुछ प्रतिबंधित करेगा, लेकिन शायद आप कोड को संकलित कर सकते हैं जो फेंकता है ChuckNorrisException, लेकिन रनटाइम में एक वर्ग परिभाषा प्रदान करता हैChuckNorrisException जिसमें थ्रोएबल का विस्तार नहीं होता है

अपडेट करें:

यह काम नहीं करता है। यह एक सत्यापन त्रुटि उत्पन्न करता है:

Exception in thread "main" java.lang.VerifyError: (class: TestThrow, method: ma\
in signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestThrow.  Program will exit.

अद्यतन 2:

वास्तव में, आप यह काम कर सकते हैं यदि आप बाइट कोड सत्यापनकर्ता को अक्षम करते हैं! ( -Xverify:none)

अद्यतन 3:

घर से निम्नलिखित लोगों के लिए, यहाँ पूरी स्क्रिप्ट है:

निम्नलिखित कक्षाएं बनाएं:

public class ChuckNorrisException
    extends RuntimeException // <- Comment out this line on second compilation
{
    public ChuckNorrisException() { }
}

public class TestVillain {
    public static void main(String[] args) {
        try {
            throw new ChuckNorrisException();
        }
        catch(Throwable t) {
            System.out.println("Gotcha!");
        }
        finally {
            System.out.println("The end.");
        }
    }
}

संकलन कक्षाएं:

javac -cp . TestVillain.java ChuckNorrisException.java

Daud:

java -cp . TestVillain
Gotcha!
The end.

बाहर टिप्पणी "RuntimeException फैली" और केवल recompileChuckNorrisException.java :

javac -cp . ChuckNorrisException.java

Daud:

java -cp . TestVillain
Exception in thread "main" java.lang.VerifyError: (class: TestVillain, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestVillain.  Program will exit.

सत्यापन के बिना चलाएं:

java -Xverify:none -cp . TestVillain
The end.
Exception in thread "main"

18
ठीक है, तो अगर आप के Objectबजाय पकड़, तो क्या Throwable? (संकलक इसे अनुमति नहीं देगा, लेकिन चूंकि हमने पहले ही सत्यापनकर्ता को अक्षम कर दिया है, हो सकता है कि कोई इसे करने के लिए
बायटेकोड

11
जावा में आप क्या फेंक सकते हैं, उसके अनुसार आप अभी भी ऐसी चीजें पकड़ सकते हैं जो फेंकने योग्य नहीं हैं, लेकिन उन्हें फेंकना और पकड़ना अपरिभाषित व्यवहार है।
VolatileDream

8
@dzieciou वे एक साथ सच हो सकते हैं। आप अपने प्रोसेसर प्रकार पर अपने ऑपरेटिंग सिस्टम के विशिष्ट संस्करण पर जावा वातावरण के अपने संस्करण का उपयोग करके उन्हें पकड़ने में सक्षम हो सकते हैं। लेकिन अगर यह मानक में निर्दिष्ट नहीं है कि क्या इसे पकड़ा जा सकता है, तो इसे अपरिभाषित व्यवहार कहा जाता है, क्योंकि जावा के अन्य कार्यान्वयन इसे गैर-उपयोग योग्य बनाने के लिए चुन सकते हैं।
Heinrich5991

2
Hmmph। मैं उम्मीद कर रहा था कि 176 अपवोट्स के लिए, आपने कुछ JNI कोड लिखे होंगे जो आपके अपवाद (बेशक, ctor द्वारा कहा जाता है) को वापस करने के लिए पूरे कॉल स्टैक को बंद करता है।
kdgregory

3
यह सब करते समय, एक पैर पर खड़े होना, अपने सिर को थपथपाना और डिक्सी को फुसफुसाते हुए अपने पेट को रगड़ना भी एक अच्छा विचार है;);)
ग्लेन बेस्ट

120

यह विचार करने के बाद, मैंने सफलतापूर्वक एक अप्राप्य अपवाद बनाया है। मैंने इसका नाम चुना JulesWinnfield, हालांकि, चक के बजाय, क्योंकि यह एक मशरूम-क्लाउड-बिछाने-मां-अपवाद है। इसके अलावा, यह वास्तव में आपके दिमाग में नहीं था, लेकिन यह निश्चित रूप से पकड़ा नहीं जा सकता है। का निरीक्षण करें:

public static class JulesWinnfield extends Exception
{
    JulesWinnfield()
    {
        System.err.println("Say 'What' again! I dare you! I double dare you!");
        System.exit(25-17); // And you shall know I am the LORD
    }
}


public static void main(String[] args)
{       
    try
    {
        throw new JulesWinnfield();
    } 
    catch(JulesWinnfield jw)
    {
        System.out.println("There's a word for that Jules - a bum");
    }
}

ए टी वॉयला! पकड़ा ना गया अपवाद।

आउटपुट:

Daud:

वही से दुबारा कहें! मैं तुम्हें चुनौती देता हूं! मुझमे तुमसे दुगुनी हिम्मत है!

जावा परिणाम: 8

निर्माण सफलता (कुल समय: 0 सेकंड)

जब मेरे पास थोड़ा और समय होगा, मैं देखूंगा कि क्या मैं किसी और चीज के साथ नहीं आ सकता।

इसके अलावा, इसे देखें:

public static class JulesWinnfield extends Exception
{
    JulesWinnfield() throws JulesWinnfield, VincentVega
    {
        throw new VincentVega();
    }
}

public static class VincentVega extends Exception
{
    VincentVega() throws JulesWinnfield, VincentVega
    {
        throw new JulesWinnfield();
    }
}


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

    try
    {
        throw new JulesWinnfield();
    }
    catch(JulesWinnfield jw)
    {

    }
    catch(VincentVega vv)
    {

    }
}

एक स्टैक ओवरफ्लो का कारण बनता है - फिर से, अपवाद अनकहा रहता है।


32
अपने जवाब में स्टैक ओवरफ्लो का उपयोग करने के लिए +1। बस मजाक कर रहे हैं, वास्तव में अच्छा जवाब।
योशिय्याह

7
एक उचित "अप्राप्य अपवाद" यह सुनिश्चित करेगा कि अंत में सभी ब्लॉक किसी भी हस्तक्षेप करने वाले कैच के बिना निष्पादित होंगे। सिस्टम को मारना अपवाद नहीं है - यह सिस्टम को मारता है।
सुपरकैट

4
आप "फेंक" कैसे करते हैं JulesWinfield? क्या सिस्टम को फेंकने से पहले एक डरावना पड़ाव पर नहीं आएगा?
सुपरैट

6
@mikeTheLiar: सिस्टम कंस्ट्रक्टर के दौरान बाहर निकलता है, है ना? बयान throw new Whatever()वास्तव में दो भाग हैं: Whatever it = new Whatever(); throw it;और दूसरे भाग तक पहुँचने से पहले सिस्टम मर जाता है।
सुपरैट

5
@mikeTheLiar आप वास्तव में जूल्स या विंसेंट को आसानी से पकड़ सकते हैं ... यदि आप इसे फेंकने का प्रबंधन करते हैं। यह एक अपवाद बनाना आसान है जिसे आप फेंक नहीं सकते हैं:class cn extends exception{private cn(){}}
जॉन डेवोरक

85

इस तरह के एक अपवाद के साथ यह स्पष्ट रूप System.exit(Integer.MIN_VALUE);से कंस्ट्रक्टर से उपयोग करने के लिए अनिवार्य होगा क्योंकि यह ऐसा होगा यदि आप इस तरह के अपवाद को फेंक देते हैं;)


32
+1; IMO यह एकमात्र संभव समाधान है। एक अप्राप्य अपवाद को कार्यक्रम को समाप्त करना चाहिए ...
घर

7
नहीं, ऐसा नहीं होगा जब आप ऐसा अपवाद फेंकते हैं। एक अनकहा अपवाद एकल थ्रेड को समाप्त कर देगा, यह jvm से बाहर नहीं निकलेगा, कुछ संदर्भों में System.exit खुद भी एक SecurityException का कारण बनेगा - कोड के प्रत्येक टुकड़े को एक कार्यक्रम को बंद करने की अनुमति नहीं है।
जोसेफ

3
आप उपयोग कर सकते हैं while(true){}के बजाय System.exit()
पियोट्र्स प्रेज़मो

2
वास्तव में, आप एक सुरक्षा प्रबंधक स्थापित करके काम करने से रोक सकते हैंSystem.exit() जो इसे अस्वीकार करता है। यह कंस्ट्रक्टर को एक अलग अपवाद (SecurityException) में बदल देगा, जिसे पकड़ा जा सकता है।
jtahlborn

5
उम्म, तकनीकी रूप से आपने कभी अपवाद नहीं फेंका । आपने अभी तक कोई वस्तु नहीं बनाई है!
थॉमस एडिंग

46

कोई भी कोड Throwable को पकड़ सकता है। तो नहीं, आप जो भी अपवाद बनाते हैं वह थ्रोबेबल का उपवर्ग होने वाला है और पकड़े जाने के अधीन होगा।


11
ChuckNorrisException hang: P
PermGenError

35
public class ChuckNorrisException extends Exception {
    public ChuckNorrisException() {
        System.exit(1);
    }
}

(दी गई, तकनीकी रूप से यह अपवाद वास्तव में कभी नहीं फेंका गया है, लेकिन एक उचित ChuckNorrisExceptionनहीं फेंका जा सकता है - यह आपको पहले फेंक देता है)


4
मेरे एक सहकर्मी ने सुझाव दिया था कि '(?;) {}' के लिए उसे 'सिस्टम.टेक्सिट (1)' कॉल एक सुरक्षा अपवाद फेंक सकता है। मैं इसे रचनात्मकता के लिए वोट कर रहा हूं!
फिल स्ट्रीट

मैं आपके उत्तर के अंत से सहमत हूं। ChuckNorris, अपवाद या नहीं के साथ गड़बड़ नहीं है।
बेंज

28

आपके द्वारा फेंके गए किसी भी अपवाद को थ्रोबेबल का विस्तार करना होगा, इसलिए इसे हमेशा पकड़ा जा सकता है। तो जवाब है नहीं।

आप यह मुश्किल को संभालने के लिए बनाना चाहते हैं, तो आप ओवरराइड कर सकते हैं तरीकों getCause(), getMessage(), getStackTrace(), toString()एक और फेंकने के लिए java.lang.ChuckNorrisException


2
हम्म, कैच (थ्रोएबल टी) किसी भी तरीके को कॉल करें या ऑब्जेक्ट को म्यूट करें? यह असंभव होने के लिए एक अपवाद को आगे फेंकने के लिए कैच क्लॉज़ का कारण हो सकता है।
Colton

1
मुझे लगता है कि catch(Throwable t)यह केवल चर में संग्रहीत करता है इसलिए मेरे सुझाव केवल अगले ब्लॉक में लागू होते हैं जब उपयोगकर्ता अपवाद के साथ सामना करना चाहता है
mirelon

24

मेरा उत्तर @ jtahlborn के विचार पर आधारित है, लेकिन यह पूरी तरह से काम करने वाला जावा प्रोग्राम है, जिसे एक JAR फ़ाइल में पैक किया जा सकता है और यहां तक ​​कि वेब एप्लिकेशन के एक हिस्से के रूप में आपके पसंदीदा एप्लिकेशन सर्वर पर भी तैनात किया जा सकता है ।

सबसे पहले, चलो ChuckNorrisExceptionवर्ग को परिभाषित करते हैं ताकि यह शुरुआत से जेवीएम को दुर्घटनाग्रस्त न करे (चक वास्तव में जेवीएम को दुर्घटनाग्रस्त करना पसंद करता है :)

package chuck;

import java.io.PrintStream;
import java.io.PrintWriter;

public class ChuckNorrisException extends Exception {

    public ChuckNorrisException() {
    }

    @Override
    public Throwable getCause() {
        return null;
    }

    @Override
    public String getMessage() {
        return toString();
    }

    @Override
    public void printStackTrace(PrintWriter s) {
        super.printStackTrace(s);
    }

    @Override
    public void printStackTrace(PrintStream s) {
        super.printStackTrace(s);
    }
}

अब Expendablesइसे बनाने के लिए कक्षा जाती है:

package chuck;

import javassist.*;

public class Expendables {

    private static Class clz;

    public static ChuckNorrisException getChuck() {
        try {
            if (clz == null) {
                ClassPool pool = ClassPool.getDefault();
                CtClass cc = pool.get("chuck.ChuckNorrisException");
                cc.setSuperclass(pool.get("java.lang.Object"));
                clz = cc.toClass();
            }
            return (ChuckNorrisException)clz.newInstance();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

और अंत में Mainक्लास को कुछ बट किक करने के लिए:

package chuck;

public class Main {

    public void roundhouseKick() throws Exception {
        throw Expendables.getChuck();
    }

    public void foo() {
        try {
            roundhouseKick();
        } catch (Throwable ex) {
            System.out.println("Caught " + ex.toString());
        }
    }

    public static void main(String[] args) {
        try {
            System.out.println("before");
            new Main().foo();
            System.out.println("after");
        } finally {
            System.out.println("finally");
        }
    }
}

निम्नलिखित कमांड के साथ इसे संकलित करें और चलाएं:

java -Xverify:none -cp .:<path_to_javassist-3.9.0.GA.jar> chuck.Main

आपको निम्न आउटपुट मिलेगा:

before
finally

कोई आश्चर्य नहीं - यह एक राउंडहाउस किक है :)


बहुत अच्छा! वर्ग परिभाषा में हेरफेर के साथ बहुत कुछ नहीं किया है। क्या आपको अभी भी कमांडलाइन पर "सत्यापित करें: कोई नहीं" चाहिए?
jtahlborn

@jtahlborn हां, थ्रोबेबल के वंशज न होने वाली वस्तु को "सत्यापित: कोई नहीं" के बिना फेंकने का प्रयास।
वाइल्डफायर

ओह, मुझे आभास हो गया कि यह किसी तरह से उस बाधा के आसपास है। तो यह मेरे उत्तर से कैसे भिन्न है?
jtahlborn 15

2
मुख्य अंतर यह है कि यह संकलन-समय हैकिंग के बिना जावा कोड काम कर रहा है
वाइल्डफेयर

15

कंस्ट्रक्टर में आप एक थ्रेड शुरू कर सकते हैं जो बार-बार कॉल करता है originalThread.stop (ChuckNorisException.this)

धागा बार-बार अपवाद को पकड़ सकता था लेकिन जब तक वह मर नहीं जाता तब तक उसे फेंकते रहेंगे।


13

नहीं। जावा में सभी अपवादों को उप-वर्ग होना चाहिए java.lang.Throwable, और यद्यपि यह अच्छा अभ्यास नहीं हो सकता है, आप हर प्रकार के अपवाद को पकड़ सकते हैं जैसे:

try {
    //Stuff
} catch ( Throwable T ){
    //Doesn't matter what it was, I caught it.
}

देखें java.lang.Throwable अधिक जानकारी के लिए प्रलेखन।

यदि आप चेक किए गए अपवादों (जिन्हें स्पष्ट रूप से नियंत्रित किया जाना चाहिए) से बचने की कोशिश कर रहे हैं, तो आप त्रुटि, या RuntimeException को उप-वर्ग करना चाहेंगे।


9

वास्तव में स्वीकृत उत्तर इतना अच्छा नहीं है क्योंकि जावा को सत्यापन के बिना चलाने की आवश्यकता है, अर्थात कोड सामान्य परिस्थितियों में काम नहीं करेगा।

वास्तविक समाधान के लिए बचाव के लिए पहलू !

अपवाद वर्ग:

package de.scrum_master.app;

public class ChuckNorrisException extends RuntimeException {
    public ChuckNorrisException(String message) {
        super(message);
    }
}

पहलू:

package de.scrum_master.aspect;

import de.scrum_master.app.ChuckNorrisException;

public aspect ChuckNorrisAspect {
    before(ChuckNorrisException chuck) : handler(*) && args(chuck) {
        System.out.println("Somebody is trying to catch Chuck Norris - LOL!");
        throw chuck;
    }
}

नमूना आवेदन:

package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        catchAllMethod();
    }

    private static void catchAllMethod() {
        try {
            exceptionThrowingMethod();
        }
        catch (Throwable t) {
            System.out.println("Gotcha, " + t.getClass().getSimpleName() + "!");
        }
    }

    private static void exceptionThrowingMethod() {
        throw new ChuckNorrisException("Catch me if you can!");
    }
}

आउटपुट:

Somebody is trying to catch Chuck Norris - LOL!
Exception in thread "main" de.scrum_master.app.ChuckNorrisException: Catch me if you can!
    at de.scrum_master.app.Application.exceptionThrowingMethod(Application.java:18)
    at de.scrum_master.app.Application.catchAllMethod(Application.java:10)
    at de.scrum_master.app.Application.main(Application.java:5)

8

थीम पर एक प्रकार आश्चर्यजनक तथ्य है कि आप जावा कोड से अघोषित जाँच अपवादों को फेंक सकते हैं। चूंकि यह विधियों के हस्ताक्षर में घोषित नहीं है, इसलिए कंपाइलर आपको अपवाद को पकड़ने नहीं देगा, हालांकि आप इसे java.lang.Exception के रूप में पकड़ सकते हैं।

यहाँ एक सहायक वर्ग है जो आपको कुछ भी फेंकने की अनुमति देता है, घोषित या नहीं:

public class SneakyThrow {
  public static RuntimeException sneak(Throwable t) {
    throw SneakyThrow.<RuntimeException> throwGivenThrowable(t);
  }

  private static <T extends Throwable> RuntimeException throwGivenThrowable(Throwable t) throws T {
    throw (T) t;
  }
}

अब throw SneakyThrow.sneak(new ChuckNorrisException());एक ChuckNorrisException को फेंक देता है, लेकिन संकलक शिकायत करता है

try {
  throw SneakyThrow.sneak(new ChuckNorrisException());
} catch (ChuckNorrisException e) {
}

एक अपवाद को पकड़ने के बारे में जो कि फेंक नहीं है अगर ChuckNorrisException एक जाँच अपवाद है।


6

ChuckNorrisExceptionजावा में एकमात्र s होना चाहिए OutOfMemoryErrorऔर StackOverflowError

आप वास्तव में उन्हें इस अर्थ में "पकड़" सकते हैं कि catch(OutOfMemoryError ex)अपवाद को फेंक दिए जाने की स्थिति में एक वसीयत निष्पादित होगी, लेकिन वह ब्लॉक स्वचालित रूप से कॉलर को अपवाद को हटा देगा।

मुझे नहीं लगता कि public class ChuckNorrisError extends Errorयह चाल है, लेकिन आप इसे आजमा सकते हैं। मुझे विस्तार के बारे में कोई दस्तावेज नहीं मिलाError


2
त्रुटि अभी भी Throwable का विस्तार करती है इसलिए इसे पकड़ने से रोकने का कोई तरीका नहीं है। यह जावा भाषा के डिजाइन द्वारा है।
जेसनएम 1

1
@ जेसनएम 1 मुझे नहीं लगता कि ओपी ने वास्तव में "अप्राप्य" अपवाद के लिए कहा था, और मेरा मतलब था कि त्रुटि भले ही इसे पकड़ ले। इसलिए, कोई भी थ्रेशेबल है, लेकिन ये दोनों अंततः किसी भी बात का प्रचार नहीं करेंगे
usr-local-at

मुश्किल ChuckNorrisException सीधे विस्तार करने योग्य हो सकता है तो यह अपवाद या त्रुटि नहीं होगी!
जेसनएम 1

4
त्रुटि तब भी नहीं फैलती है जब आप इसे पकड़ लेते हैं, मुझे यकीन नहीं है कि आपको वह विचार कहां मिला है।
jtahlborn

3
मुझे लगता है कि आप एरोस के बारे में अच्छी तरह से भ्रमित हैं, वे सामान्य अपवाद हैं जैसे कि थ्रोबेबल या थ्रोएबल, स्वयं भी।
10

6

Is it possible to construct a snippet of code in java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?

हां, और यहां उत्तर है: अपना डिजाइन java.lang.ChuckNorrisExceptionऐसा बनाएं कि वह इसका उदाहरण न हो java.lang.Throwable। क्यों? एक अप्राप्य वस्तु परिभाषा के द्वारा उपलब्ध नहीं है क्योंकि आप कभी भी ऐसी चीज नहीं पकड़ सकते जिसे कभी फेंका न जा सके।


2
लेकिन तब यह अपवाद नहीं है।
डोलबी

8
@ डॉली: मुझे ओपी के सवाल में कोई जगह नहीं मिल रही है कि राज्यों java.lang.ChuckNorrisExceptionको एक अपवाद होना चाहिए, अकेले फेंकने योग्य हो
थॉमस एडिंग

1
मुझे लगता है कि इसका उल्लेख नहीं किया गया है, लेकिन यह निहित है। आप एक गणितज्ञ हैं :-), क्या आप नहीं हैं?
डोलबी

3

आप चकोरनिरिस को आंतरिक या निजी रख सकते हैं और उसे एनकैप्सुलेट कर सकते हैं या उसे निगल सकते हैं ...

try { doChuckAction(); } catch(ChuckNorrisException cne) { /*do something else*/ }


7
मुझे विश्वास नहीं है कि विचार इसे पकड़ने के लिए था। मुझे लगता है कि यह विचार इसे पकड़े जाने से रोकने के लिए है।
पैट्रिक रॉबर्ट्स

अगर मैं गलत हूं तो मुझे सुधारें लेकिन अगर आप इसे आंतरिक बनाते हैं तो आप इसे प्रतिबिंब के बिना प्राप्त नहीं कर सकते।
जय

5
हां, लेकिन जब तक आप एक्सेप्शन या थ्रोबेबल को पकड़ सकते हैं तब तक वास्तविक प्रकार की दृश्यता अप्रासंगिक है।
कीथ्स

3

जावा में अपवाद हैंडलिंग के साथ दो मूलभूत समस्याएं हैं कि यह इस बात का संकेत देने के लिए अपवाद के प्रकार का उपयोग करता है कि क्या इसके आधार पर कार्रवाई की जानी चाहिए, और जो कुछ भी अपवाद के आधार पर कार्रवाई करता है (यानी "पकड़" तों) इसे हल करने के लिए माना जाता है अंतर्निहित स्थिति। ऐसे साधनों का उपयोग करना उपयोगी होगा जिनके द्वारा एक अपवाद वस्तु तय कर सकती है कि किन हैंडलर को निष्पादित करना चाहिए, और क्या अभी तक निष्पादित हैंडलर ने मौजूदा निकास विधि को पूरा करने के लिए चीजों को साफ किया है। हालांकि इसका उपयोग "अनटचेबल" अपवादों को करने के लिए किया जा सकता है, दो बड़े उपयोग (1) अपवाद बनाने के लिए किए जाएंगे, जिन्हें केवल तब ही हैंडल किया जाएगा जब वे कोड द्वारा पकड़े जाएंगे जो वास्तव में जानते हैं कि उनके साथ कैसे व्यवहार करें,finallyFooExceptionएक finallyब्लॉक की अवधि के दौरान BarException, दोनों अपवादों को कॉल स्टैक का प्रचार करना चाहिए; दोनों को कैच करने योग्य होना चाहिए, लेकिन जब तक दोनों को पकड़ा नहीं जाता है तब तक अन्डरलाइन जारी रहना चाहिए)। दुर्भाग्य से, मुझे नहीं लगता कि चीजों को तोड़े बिना मौजूदा अपवाद-हैंडलिंग कोड काम करने का कोई तरीका होगा।


एक दिलचस्प विचार है, लेकिन मुझे नहीं लगता कि निम्न-स्तरीय कोड को पता होगा कि एक विशेष अपवाद का क्या मतलब है "कॉल करने वाले के लिए", इसलिए मुझे नहीं लगता कि यह फेंकने वाले के लिए कभी भी यह तय करना होगा कि कौन से हैंडलर को निष्पादित करना चाहिए।
jtahlborn

@jtahlborn: अभी, फेंकने वाला तय करता है कि अपवाद प्रकार की पसंद के माध्यम से किन अपवाद संचालकों को निष्पादित करना चाहिए। यह सब कुछ स्पष्ट रूप से कुछ परिदृश्यों को संभालना असंभव बनाता है। अन्य बातों के अलावा: (1) यदि एक अपवाद तब होता है जब एक finallyब्लॉक पहले के अपवाद से सफाई कर रहा है, तो यह बहुत संभव है कि या तो अपवाद, दूसरे की अनुपस्थिति में, कुछ ऐसा कोड हो सकता है जिस पर कोड को संभालने और जारी रखने की उम्मीद होगी। लेकिन यह कि एक को संभालना और दूसरे की अनदेखी करना बुरा होगा। हालांकि, कोई भी तंत्र नहीं है, एक समग्र अपवाद का उत्पादन करने के लिए कि दोनों हैंडलर प्रक्रिया करेंगे।
सुपरकाट

@jtahlborn: इसके अलावा, यह बाहरी अनुप्रयोग परत द्वारा नियंत्रित किए जाने वाले कॉलबैक के भीतर होने वाले अपवादों को अनुमति देने के लिए बहुत मुश्किल बनाता है। यदि कॉलबैक का अपवाद किसी अन्य अपवाद प्रकार में लिपटा हुआ है, तो कॉलबैक अपवाद के प्रकार का उपयोग यह तय करने में बाहरी परत में नहीं किया जा सकता है कि क्या इसे पकड़ना है; यदि यह लिपटा हुआ नहीं है, तो कॉलबैक में होने वाले एक "आकस्मिक" मिड-लेयर अपवाद को गलत किया जा सकता है। यदि एक लिपटा अपवाद वस्तु को बताया गया था जब इसे बाहरी अनुप्रयोग परत तक पारित किया गया था, तो यह लिपटे अपवादों के प्रकारों का उत्तर देना शुरू कर सकता है।
सुपरकैट

मैं आपके अन्य बिंदुओं पर बहस नहीं कर रहा था, सिर्फ अपवाद वस्तु के बारे में बयान, जिस पर हैंडलर निष्पादित करेगा। कुछ हद तक अपवाद प्रकार पहले से ही करते हैं, लेकिन ऐसा लगता है कि आप कुछ अधिक गतिशील चाहते थे, जिससे मैं असहमत था। मुझे लगता है कि आपका प्रमुख तर्क (जो आप बग़ल में आने की तरह हैं) आपको नीचे की तरफ जितनी जानकारी मिल सकती है, उतनी जानकारी हासिल करने के लिए और ऊपरी परतों को उस जानकारी के साथ देखने और काम करने दें । इस सामान्य बिंदु पर मैं आपसे सहमत हूँ, हालाँकि शैतान विवरण / कार्यान्वयन में है।
jtahlborn

@jtahlborn: मेरा इरादा आभासी तरीकों को विशेष रूप से "गतिशील" कुछ भी लागू करने का नहीं था, लेकिन अनिवार्य रूप से कहते हैं "क्या संकेतित प्रकार की स्थिति है जिस पर कार्य किया जाना चाहिए"। एक बात जिसका मैं उल्लेख करना भूल गया, हालाँकि, यह है कि कोई ऐसा साधन होना चाहिए जिसके माध्यम से कोड को कॉल Fooअपवाद के बीच अंतर कर सकता है जो Fooया तो खुद को फेंक देता है या जानबूझकर इसे नाटक करना चाहता है, खुद को फेंक दिया है, जो Fooकि होने की उम्मीद नहीं थी। किसी और तरीके से फोन करना। यही "जाँच" अपवादों की धारणा "के बारे में" होनी चाहिए।
सुपरकैट

1

वर्तमान थ्रेड पर एक अनकहा अपवाद को अनुकरण करना आसानी से संभव है। यह बिना किसी अपवाद के नियमित व्यवहार को ट्रिगर करेगा, और इस प्रकार कार्य को शब्दार्थ से पूरा करता है। हालांकि, यह जरूरी नहीं कि वर्तमान थ्रेड के निष्पादन को रोकें, क्योंकि वास्तव में कोई अपवाद नहीं फेंका गया है।

Throwable exception = /* ... */;
Thread currentThread = Thread.currentThread();
Thread.UncaughtExceptionHandler uncaughtExceptionHandler =
    currentThread.getUncaughtExceptionHandler();
uncaughtExceptionHandler.uncaughtException(currentThread, exception);
// May be reachable, depending on the uncaught exception handler.

यह वास्तव में (बहुत दुर्लभ) स्थितियों में उपयोगी है, उदाहरण के लिए जब उचित Errorहैंडलिंग की आवश्यकता होती है, लेकिन विधि किसी भी फ्रेमवर्क को पकड़ने (और त्यागने) से होती है Throwable


0

System.exit (1) को कॉल करें finalize, और बाकी सभी तरीकों से अपवाद की एक प्रति फेंक दें, ताकि प्रोग्राम बाहर निकल जाए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.