मैंने अक्सर ढांचे या पुस्तकालयों जैसे हाइबरनेट या स्प्रिंग संदर्भ द्वारा फेंक दिया अपवाद देखा है (प्रक्रिया में डीबगर जीयूआई को भ्रमित कर रहा है)।
मुझे हमेशा आश्चर्य हुआ कि उन्होंने ऐसा क्यों किया क्योंकि ऐसा लगता है कि ऐसा बुरा विचार है। और आज यह वास्तव में एक समस्या का कारण बन गया जब मैं एक 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
विधि को कॉल करें, अपवाद का कारण स्वयं ही होगा!
तो मुझे लगता है कि इसे एक बहुत ही आम घटना बनाना चाहिए।
खराब कोडिंग अभ्यास, अगर अपवाद पहले से ही कारण है, तो इसे किसी मूल कारण को परिभाषित करने की आवश्यकता नहीं है। –
ज़रूर ... यदि आप चाहते हैं * एक परिपत्र निर्भरता बनाना चाहते हैं जिससे कोई भाग नहीं निकलता है। मैं किसी भी तरह सोच रहा हूं कि कोड ऐसा नहीं कर रहा है जो आपको लगता है कि यह कर रहा है। –
भी बुरा अभ्यास, लेकिन ऐसा हो सकता है कि एक कोड अपवाद एक्स पकड़ता है, और एक नया अपवाद एक्स फेंकता है, पुराने कारण के कारण। तो वे समान दिख सकते हैं, लेकिन वास्तव में अलग अपवाद। – Luciano