क्या थ्रो डिक्लेरेशन को जोड़े बिना अपवाद फेंकने का कोई तरीका है?


81

मेरी निम्नलिखित स्थिति है।

मेरे पास एक जावा क्लास है जो दूसरे बेस क्लास से विरासत में मिली है और एक विधि को ओवरराइड करती है। आधार विधि अपवादों को नहीं फेंकती है और इस प्रकार इसकी कोई throws ...घोषणा नहीं है ।

अब मेरी खुद की विधि अपवाद को फेंकने में सक्षम होनी चाहिए, लेकिन मेरे पास या तो विकल्प है

  • अपवाद निगल
  • एक फेंकता घोषणा जोड़ें

दोनों संतुष्ट नहीं हैं क्योंकि पहले वाला चुपचाप अपवाद को अनदेखा करेगा (ठीक है मैं कुछ लॉगिंग कर सकता था) और दूसरा अलग-अलग विधि हेडर के कारण कंपाइलर त्रुटियां उत्पन्न करेगा।

public class ChildClass extends BaseClass {

        @Override 
        public void SomeMethod() {
            throw new Exception("Something went wrong");
        }
}

जवाबों:


99

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

एक विशिष्ट मामले के रूप में, जावा 8 UncheckedIOExceptionरैपिंग और रीथ्रोइंग के लिए जोड़ा गया IOException


1
महान काम करता है, मुझे एक RuntimeException को पुनर्विचार करना होगा क्योंकि अपवाद दूसरी विधि से आता है लेकिन यह महान काम करता है, धन्यवाद।
जर्गेन स्टीनब्लॉक

42

यहाँ एक चाल है:

class Utils
{
    @SuppressWarnings("unchecked")
    private static <T extends Throwable> void throwException(Throwable exception, Object dummy) throws T
    {
        throw (T) exception;
    }

    public static void throwException(Throwable exception)
    {
        Utils.<RuntimeException>throwException(exception, null);
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Utils.throwException(new Exception("This is an exception!"));
    }
}

मुझे आश्चर्य है कि यह कैसे काम करता है? मैं कुछ शोध करूंगा, लेकिन क्या आपके पास कोई संसाधन हैं, जो मेरी मदद कर सकते हैं? :-)
होलीमेज़

T, RuntimeException के रूप में अनुमानित है। यहां उत्तर दिया गया है stackoverflow.com/questions/41380656/… और यहाँ stackoverflow.com/questions/31316581/…
sawimurugan

1
बहुत बढ़िया चाल! यह ट्रिक लैम्ब्डा एक्सप्रेशन / ब्लॉक पर भी लागू हो सकती है, किसी भी throwsघोषणा के बिना एसएएम इंटरफेस को चेक-अपवाद पद्धति को असाइन करने की अनुमति देता है ।
जेसनमिंग

असुरक्षित के साथ सौदा नहीं करने के लिए अतिरिक्त सुपर जोड़ा बोनस है।
lscoughlin

आपको डमी पैरामीटर की आवश्यकता क्यों है? इसके अलावा, क्या यह कार्य जेनेरिक विधि के बिना हो सकता है?
Kiruahxh

28

एक तीसरा विकल्प अपवाद जाँच से बाहर निकलने का है (ठीक उसी तरह जैसे कि मानक एपीआई को कभी-कभी करना पड़ता है) और जाँच अपवाद को एक में लपेटें RuntimeException:

throw new RuntimeException(originalException);

आप एक अधिक विशिष्ट उपवर्ग का उपयोग करना चाह सकते हैं RuntimeException


10

मैं केवल एक वैकल्पिक उत्तर जोड़ना चाहता हूं, विशुद्ध रूप से एक FYI के रूप में :

हां, कक्षा throwsका उपयोग करके, घोषणा को जोड़े बिना चेक किए गए अपवाद को फेंकने का एक तरीका है sun.misc.Unsafe। यह निम्नलिखित ब्लॉग पोस्ट में वर्णित है:

घोषित किए बिना एक विधि से एक चेक किए गए अपवाद को फेंक दें

नमूना कोड:

public void someMethod() {
  //throw a checked exception without adding a "throws"
  getUnsafe().throwException(new IOException());
}

private Unsafe getUnsafe() {
  try {
    Field field = Unsafe.class.getDeclaredField("theUnsafe");
    field.setAccessible(true);
    return (Unsafe) field.get(null);
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}

हालांकि, यह अनुशंसित नहीं है। अनियंत्रित अपवाद में लपेटना बेहतर है जैसा कि कुछ अन्य उत्तरों में उल्लिखित है।


3
एक कारण है कि वे उस वर्ग को बुलाते हैं Unsafe
ऑरेंजडॉग

4

आप अनियंत्रित अपवाद क्यों नहीं फेंकते? इसे घोषित नहीं किया जाना है।

दो विकल्प हैं

  • एक अनियंत्रित एक के साथ एक जाँच अपवाद के साथ लपेटो।
  • संकलक को यह पता न चलने दें कि आप एक चेक किए गए अपवाद को फेंक रहे हैं जैसे Thread.currentThread ()। stop (e);
  • जावा 6 में, आप अपवाद को हटा सकते हैं यदि यह है finalऔर संकलक को पता है कि आपके द्वारा पकड़े गए अपवादों की जाँच की जा सकती है।
  • जावा 7 में, आप एक अपवाद को हटा सकते हैं यदि यह प्रभावी रूप से अंतिम है, अर्थात आप इसे कोड में नहीं बदलते हैं।

बाद में अधिक उपयोगी होता है जब आप एक चेक अपवाद को अपने कोड में फेंक रहे हैं और इसे अपने कॉलिंग कोड में पकड़ रहे हैं, लेकिन परतों के इनबेटवाइन्स को अपवाद के बारे में कुछ भी पता नहीं है।


दूसरी विधि अन्योन्याश्रित है। लेकिन फिलहाल, अपवाद को लपेटना वास्तव में मेरी आवश्यकता है।
जर्गेन स्टाइनब्लॉक


@OrangeDog, चूंकि आपने इसे पढ़ा है, क्या आप मुझे बता सकते हैं कि वर्तमान थ्रेड पर स्टॉप () का उपयोग करने और एक लिपटे अपवाद को फेंकने के बीच क्या अंतर है। ;)
पीटर लॉरी

"निम्न विधि व्यवहारिक रूप से जावा के थ्रो ऑपरेशन के समान है, लेकिन यह सुनिश्चित करने के लिए कंपाइलर के प्रयासों को दरकिनार कर देता है कि कॉलिंग विधि ने सभी चेक किए गए अपवादों को घोषित कर दिया है कि यह फेंक सकता है" अपवाद को किसी भी बेहतर तरीके से कैसे लपेट रहा है?
पीटर लॉरी

"एक थ्रेड को रोकने से यह सभी मॉनिटरों को अनलॉक करने का कारण बनता है जो इसे बंद कर दिया है। यदि इन मॉनीटरों द्वारा पहले संरक्षित कोई भी वस्तु असंगत स्थिति में थी, तो अन्य थ्रेड्स अब इन ऑब्जेक्ट्स को असंगत स्थिति में देख सकते हैं। [...] इसके विपरीत। अन्य अनियंत्रित अपवाद [...] उपयोगकर्ता को कोई चेतावनी नहीं है कि उसका कार्यक्रम दूषित हो सकता है। "
ऑरेंजडॉग

4

हाँ, ऐसा क्यों है, लेकिन इसका उपयोग करने की अनुशंसा नहीं की जाती है:

जावा असुरक्षित पैकेज

getUnsafe().throwException(new IOException());

इस पद्धति ने अपवाद की जाँच की, लेकिन आपका कोड इसे पकड़ने या पुन: फेंकने के लिए मजबूर नहीं हुआ। जैसे रनटाइम अपवाद।


2

चेक किए गए अपवादों को रोकने और उन्हें अनियंत्रित अपवाद में लपेटने के लिए एक उदाहरण यहां दिया गया है:

public void someMethod() {
   try {
      doEvil();
   }
   catch (IOException e)
   {
       throw new RuntimeException(e);
   }
}

-1

आप अपने तरीके से ओवरराइड किए गए प्रयास को पकड़ सकते हैं। फिर आपको थ्रोट-स्टेटमेंट घोषित करने की आवश्यकता नहीं है।


2
यकीन है, लेकिन फिर मैं अपवाद को निगल जाएगा, जो कि मैं क्या हासिल करना चाहता हूं, इसके बिल्कुल विपरीत है;)
जुरगेन स्टाइनब्लॉक

-1

आप RuntimeException या RuntimeException से प्राप्त किसी भी अपवाद का उपयोग कर सकते हैं

या

अपवाद फेंकने वाले कोड के लिए एक कोशिश ब्लॉक का उपयोग करें और इसे वहां संभाल लें

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