2012-02-10 17 views
5

मैं जावा पुस्तकालयों में कुछ स्थानों पर आया हूं जिनके खिलाफ मैं निर्माण कर रहा हूं जहां अपवाद का कारण अपवाद पर ही सेट है।क्या अपवाद के कारण को स्वयं निर्धारित करने का कोई कारण है?

क्या इसके कारण के रूप में खुद को संदर्भित करने के अपवाद का कोई कारण है?

संपादित

के रूप में अनुरोध किया है, यहाँ एक ठोस उदाहरण है:

enter image description here

+2

खराब कोडिंग अभ्यास, अगर अपवाद पहले से ही कारण है, तो इसे किसी मूल कारण को परिभाषित करने की आवश्यकता नहीं है। –

+3

ज़रूर ... यदि आप चाहते हैं * एक परिपत्र निर्भरता बनाना चाहते हैं जिससे कोई भाग नहीं निकलता है। मैं किसी भी तरह सोच रहा हूं कि कोड ऐसा नहीं कर रहा है जो आपको लगता है कि यह कर रहा है। –

+0

भी बुरा अभ्यास, लेकिन ऐसा हो सकता है कि एक कोड अपवाद एक्स पकड़ता है, और एक नया अपवाद एक्स फेंकता है, पुराने कारण के कारण। तो वे समान दिख सकते हैं, लेकिन वास्तव में अलग अपवाद। – Luciano

उत्तर

2

नहीं, यह सिर्फ खराब डिज़ाइन है। यदि अपवाद मूल कारण है, तो इसे किसी कारण को परिभाषित करने की आवश्यकता नहीं है।

एक अपवाद जिसका कारण है अपवाद अपवाद लपेटने के लिए एक कानूनी मामला है। उदाहरण के लिए, यदि एक दृढ़ता स्टोर बनाते हैं, तो आप एक PersistenceExcpetion फेंकना चाह सकते हैं। तो फिर यदि यह एक फ़ाइल स्टोर है, तो आपके पास कारण IOException हो सकता है। यदि यह डेटाबेस है, तो शायद कारण एक एसक्यूएलएक्सप्शन है। आदि

3

Throwable के स्रोतों से मैं यहाँ है:

public synchronized Throwable initCause(Throwable cause) { 
    ... 
    if (cause == this) 
     throw new IllegalArgumentException("Self-causation not permitted"); 
    ... 
} 

मैं नहीं दिख रहा है कैसे खुद को सेटिंग कारण संभव है।

+0

आईआईआरसी, जब मैंने इसे देखा है तो यह ओआरएम परत से विशिष्ट अपवादों में रहा है। इस बात पर विश्वास करने का कोई कारण नहीं है कि 'थ्रोटेबल' इसे 'initCause' विधि में अस्वीकार करता है क्योंकि मैंने जो अपवाद देखा है, वैसे ही व्यवहार करता है। – arootbeer

+0

यह देखने के लिए पियरे हेनरी का जवाब देखें कि यह कैसे संभव है। – ctomek

7

मैंने अक्सर ढांचे या पुस्तकालयों जैसे हाइबरनेट या स्प्रिंग संदर्भ द्वारा फेंक दिया अपवाद देखा है (प्रक्रिया में डीबगर जीयूआई को भ्रमित कर रहा है)।

मुझे हमेशा आश्चर्य हुआ कि उन्होंने ऐसा क्यों किया क्योंकि ऐसा लगता है कि ऐसा बुरा विचार है। और आज यह वास्तव में एक समस्या का कारण बन गया जब मैं एक JSON को क्रमबद्ध करने की कोशिश कर रहा था: बाम, अनंत चक्र।

तो मैं इसे थोड़ा आगे की जांच की:

Throwable के स्रोत कोड में (सभी स्रोत यहाँ सूचीबद्ध कोड JDK 1.7 से है) हम इस राशि:

/** 
    * The throwable that caused this throwable to get thrown, or null if this 
    * throwable was not caused by another throwable, or if the causative 
    * throwable is unknown. If this field is equal to this throwable itself, 
    * it indicates that the cause of this throwable has not yet been 
    * initialized. 
    * 
    * @serial 
    * @since 1.4 
    */ 
    private Throwable cause = this; 

अब मैं विशेष रूप से समस्या से मुलाकात की एक अपवाद वर्ग के साथ जो RuntimeException बढ़ा, इसलिए मैं वहां से गया। RuntimeException के निर्माताओं में से एक:

/** Constructs a new runtime exception with the specified detail message. 
    * The cause is not initialized, and may subsequently be initialized by a 
    * call to {@link #initCause}. 
    * 
    * @param message the detail message. The detail message is saved for 
    *   later retrieval by the {@link #getMessage()} method. 
    */ 
    public RuntimeException(String message) { 
     super(message); 
    } 

Exception के निर्माता ऊपर से बुलाया:

/** 
    * Constructs a new exception with the specified detail message. The 
    * cause is not initialized, and may subsequently be initialized by 
    * a call to {@link #initCause}. 
    * 
    * @param message the detail message. The detail message is saved for 
    *   later retrieval by the {@link #getMessage()} method. 
    */ 
    public Exception(String message) { 
     super(message); 
    } 

Throwable के निर्माता ऊपर से बुलाया:

/** 
    * Constructs a new throwable with the specified detail message. The 
    * cause is not initialized, and may subsequently be initialized by 
    * a call to {@link #initCause}. 
    * 
    * <p>The {@link #fillInStackTrace()} method is called to initialize 
    * the stack trace data in the newly created throwable. 
    * 
    * @param message the detail message. The detail message is saved for 
    *   later retrieval by the {@link #getMessage()} method. 
    */ 
public Throwable(String message) { 
    fillInStackTrace(); 
    detailMessage = message; 
} 

fillInStackTrace एक देशी तरीका है और कारण क्षेत्र को संशोधित करने के लिए प्रतीत नहीं होता है।

तो जैसा कि आप देख सकते हैं, जब तक कि initCause विधि बाद में कहा जाता है, cause क्षेत्र कभी नहीं this के मूल मूल्य से बदला गया है।

निष्कर्ष: यदि आपके द्वारा बनाए गए एक नए नहीं Exception (या कई कई उपवर्गों कि जंगली में मौजूद हैं और इस व्यवहार को ओवरराइड नहीं है में से एक) एक निर्माता है कि एक cause तर्क नहीं ले करता है का उपयोग कर, और तुम क्या initCause विधि को कॉल करें, अपवाद का कारण स्वयं ही होगा!

तो मुझे लगता है कि इसे एक बहुत ही आम घटना बनाना चाहिए।

+1

आप वास्तव में 'अपवाद पूर्व = नया रनटाइम अपवाद ("पूर्व") कर सकते हैं, लेकिन' ex.equals (ex.getCause()) '' थ्रोबल 'की वजह से 'ex.equals (ex.getCause())' अभी भी 'झूठी' वापस कर देगा 'कार्यान्वयन: 'इसे वापस करें। == यह? शून्य: this.cause;' – Vladimir

7

स्वीकृत उत्तर भ्रामक है, और अन्य उत्तरों अपूर्ण हैं। तो ...

जबकि अपने स्वयं के कारण के रूप में अपवाद में पास करने के लिए खराब डिज़ाइन होगा, ठीक उसी कारण के लिए थ्रोबल कार्यान्वयन में संभव नहीं है। कारण या तो निर्माण के दौरान या तो initCause() विधि के लिए पारित किया गया है, और जैसा कि दूसरे उत्तर में बताया गया है, बाद वाला एक अवैध आर्ग्यूमेंट अपवाद का कारण बन जाएगा।

तीसरे उत्तर के मुताबिक, यदि आप कोई कारण नहीं देते हैं, तो कारण यह थ्रोबल कार्यान्वयन के अनुसार होगा।

क्या हो सकता है ग़ायब हैं (मूल प्रश्न दिए गए) है कि फेंकने योग्य की विधि getCause() कभी इस वापस नहीं करता है, यह शून्य अगर कारण == इस देता है। तो यद्यपि आपका डीबगर दिखा रहा है, यह कारण के रूप में संदर्भ है क्योंकि यह प्रतिबिंब का उपयोग कर रहा है, थ्रोबल के सार्वजनिक इंटरफ़ेस का उपयोग करते समय आप इसे नहीं देख पाएंगे और इसलिए यह कोई समस्या नहीं होगी।

संबंधित मुद्दे