मैं मूल कारणों के रूप में अपवादों का संग्रह कैसे पारित कर सकता हूं?


52

कुछ विधि, myMethodकई समानांतर निष्पादन को लागू करती है और उनकी समाप्ति की प्रतीक्षा करती है।

ये समानांतर निष्पादन अपवादों के साथ समाप्त हो सकते हैं। इसलिए myMethodएक अपवाद सूची मिलती है।

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


3
.NET में AggregateExceptionअपवादों की एक सूची है। यह विचार जावा पर भी लागू होना चाहिए।
usr

जवाबों:


49

मुझे यकीन नहीं है कि मैं ऐसा करूंगा (हालांकि मुझे जावाडॉक दिया गया था, मैं आपको बता नहीं सकता कि मैं क्यों झिझकता हूं), लेकिन वहाँ पर दबाए गए अपवादों की सूची है Throwable, जिन्हें आप जोड़ सकते हैं addSuppressed। JavaDoc यह कहने की जरूरत नहीं है कि यह केवल JVM के लिए उपयोग के साथ संसाधनों के लिए है:

अपवादों को निर्दिष्ट अपवाद को जोड़ता है जो इस अपवाद को वितरित करने के लिए दबाए गए थे। यह विधि थ्रेड-सुरक्षित है और आमतौर पर कोशिश-के-संसाधनों के बयान द्वारा (स्वचालित रूप से और संक्षेप में) कहा जाता है।

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

ध्यान दें कि जब एक अपवाद दूसरे अपवाद का कारण बनता है, तो पहला अपवाद आमतौर पर पकड़ा जाता है और फिर दूसरे अपवाद को प्रतिक्रिया में फेंक दिया जाता है। दूसरे शब्दों में, दो अपवादों के बीच एक कारण संबंध है। इसके विपरीत, ऐसी परिस्थितियां हैं जहां दो स्वतंत्र अपवादों को सिबलिंग कोड ब्लॉक में फेंका जा सकता है, विशेष रूप से एक कोशिश के साथ-साथ संसाधनों के स्टेटमेंट ब्लॉक में और कंपाइलर-जनरेट अंततः ब्लॉक जो संसाधन बंद कर देता है। इन स्थितियों में, फेंके गए अपवादों में से केवल एक को ही प्रचारित किया जा सकता है। ट्राई-रि-रिसोर्स स्टेटमेंट में, जब दो ऐसे अपवाद होते हैं, तो ट्राई ब्लॉक से उत्पन्न होने वाले अपवाद का प्रसार होता है और अंत में ब्लॉक से अपवाद को प्रयास ब्लॉक से अपवाद द्वारा दबाए गए अपवादों की सूची में जोड़ा जाता है। एक अपवाद के रूप में ढेर को उजागर करता है,

एक अपवाद एक अपवाद के कारण होने पर भी अपवादों को दबा सकता है। अपवाद का कोई कारण होता है या नहीं, इसके निर्माण के समय शब्दार्थ ज्ञात होता है, इसके विपरीत कोई अपवाद अन्य अपवादों को दबाएगा भी या नहीं, यह आमतौर पर अपवाद के फेंकने के बाद ही निर्धारित होता है।

ध्यान दें कि प्रोग्रामर लिखित कोड इस पद्धति को उन स्थितियों में कॉल करने का लाभ उठाने में सक्षम है जहां कई सिबलिंग अपवाद हैं और केवल एक को प्रचारित किया जा सकता है।

ध्यान दें कि अंतिम पैराग्राफ, जो आपके मामले के अनुरूप लगता है।


[...] एक अपवाद अन्य अपवादों को दबाएगा या नहीं [...] आम तौर पर केवल एक अपवाद को फेंक दिए जाने के बाद निर्धारित होता है। मुझे लगता है कि ऐसा नहीं होगा जब समानांतर रनों से कई दबाए गए अपवाद एकत्र किए जाएंगे।
गोटो 0

24

अपवाद और उनके कारण हमेशा केवल 1: 1 चीज होते हैं: आप एक अपवाद को फेंक सकते हैं और प्रत्येक अपवाद में केवल एक कारण हो सकता है (जो फिर से एक कारण हो सकता है ...)।

जब आप वर्णित के रूप में बहु-थ्रेडेड व्यवहार पर विचार कर रहे हैं, तो इसे एक डिज़ाइन दोष माना जा सकता है।

यही कारण है कि जावा 7 addSuppressedको फेंकने योग्य में जोड़ा गया है, जो मूल रूप से अपवादों की एक मनमानी राशि को एक दूसरे से जोड़ सकता है (अन्य प्राथमिक प्रेरणा का प्रयास-संसाधनों के साथ किया गया था, जिसे चुपचाप छोड़ने के बिना अंततः ब्लॉक में अपवादों को संभालने का एक तरीका चाहिए था। उन्हें)।

इसलिए मूल रूप से जब आपके पास 1 अपवाद होता है जो आपकी प्रक्रिया को विफल कर देता है, तो आप उसको अपने उच्च-स्तरीय अपवाद के कारण के रूप में जोड़ते हैं, और यदि आपके पास कोई और है, तो आप उन मूल का उपयोग करके जोड़ते हैं addSuppressed। विचार यह है कि पहले अपवाद "दूसरों को" असली अपवाद श्रृंखला "का सदस्य बनने के लिए" दमित "।

नमूना कोड:

Exception exception = null;
for (Foobar foobar : foobars) {
  try {
    foobar.frobnicate();
  } catch (Exception ex) {
    if (exception == null) {
      exception = ex;
    } else {
      exception.addSuppressed(ex);
    }
  }
}
if (exception != null) {
  throw new SomethingWentWrongException(exception);
}

4
जब तक आप अंतर्निहित अपवादों में से एक को वास्तव में "मुख्य" एक के रूप में नहीं निकाल सकते, तब तक मैं आपके सुझाव के अनुसार ऐसा नहीं करूंगा। यदि आप मनमाने ढंग से अपवादों में से किसी एक को मुख्य के रूप में और दूसरों को दबाए हुए के रूप में चुनते हैं, तो आप एक कॉलर को दबाए गए अपवादों को अनदेखा करने के लिए आमंत्रित कर रहे हैं और मुख्य रिपोर्ट करें - भले ही "मुख्य" अपवाद एक TypoInUnInputException और एक हो दमन करने वाले एक DatabaseCorruptedException हैं।
इल्मरी करोनन

1
… इसके बजाय, मैं SomeWentWrongException द्वारा दबाए गए सभी अंतर्निहित अपवादों को चिह्नित करूंगा , और उस अपवाद को एक संदेश स्पष्ट रूप से इंगित करता हूं कि एक या एक से अधिक दबाए गए अपवादों का पालन करना चाहिए , जैसे कुछ " एक्स आउट ऑफ वाई कार्यों में असफल रहा, नीचे विफलताओं की सूची देखें" "।
इल्मरी करोनन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.