2016-10-06 9 views
6

java.lang.Exception वर्ग पर Javadocs से:क्या जावा का चेक अपवाद हैंडलिंग टूटा हुआ है?

जांचे हुए अपवादों एक विधि या निर्माता के में घोषित किए जाने की जरूरत खंड फेंकता है तो वे विधि के निष्पादन या निर्माता द्वारा फेंका जा सकता है और विधि या निर्माता सीमा के बाहर प्रचार ।

लेकिन इस कोड पर विचार करें:

package other; 

public class CheckedExceptionHandling { 

    private static <E extends Exception> void throwException() throws E { 
     throw (E) new CheckedException2(); // unchecked cast warning 
    } 

    private static void setUncaughtExceptionHandler() { 
     Thread.currentThread().setUncaughtExceptionHandler((t, e) -> { 
      System.out.println("Unhandled exception: " + e.getClass()); // reports CheckedExceptionHandling$CheckedException2 
     }); 
    } 

    public static void main(String[] args) /* no checked exceptions declared! */ { 
     setUncaughtExceptionHandler(); 
     try { 
      CheckedExceptionHandling.<CheckedException1>throwException(); 
     } catch (CheckedException1 e) { 
      System.out.println(e); // never gets here 
     } 
    } 
    // checked exceptions: 
    public static class CheckedException1 extends Exception {} 
    public static class CheckedException2 extends Exception {} 

} 

यह एक चेतावनी के साथ संकलित करता है तथा रन-टाइम परिणाम है:

क्रिया के अपवाद: वर्ग other.CheckedExceptionHandling $ CheckedException2

मुझे एक संकलन-समय त्रुटि unreported exception CheckedException2; must be caught or declared to be thrown याकी उम्मीद थीया कम से कम ClassCastException रन टाइम पर।
लेकिन कंपाइलर एक अपवाद अपवाद हैंडलर पर main विधि के बाहर अनचाहे, अविकसित और प्रसारित करने के लिए एक चेक अपवाद को छोड़ने की अनुमति देता है।
क्यों? क्या मुझसे कोई चूक हो रही है?

+0

प्लस वन। अच्छा अच्छी तरह से लिखा प्रश्न। जावा अपवाद हैंडलिंग टूटा हुआ है। आखिरकार आप इसका इस्तेमाल करेंगे और शांत हो जाएंगे। – Bathsheba

+1

यहां कुछ भी टूटा नहीं है। यह सब spec के अनुसार है। – Tunaki

+2

यह "स्नीकी फेंक" की तरह दिखता है। पसंद के अपने खोज इंजन पर शब्द की खोज करें, उदा। https://www.reddit.com/r/programming/comments/2x41h4/sneaky_exceptions_in_java/ –

उत्तर

0

समस्या यह है कि संकलक पिछले विधि सीमाओं को नहीं देखता है। फेंकता एक्सेप्शन() में, "अपवाद को विस्तारित करने" के अलावा ई के बारे में कोई जानकारी नहीं है, इसलिए कंपाइलर प्रमाण नहीं दे सकता कि कास्ट गलत है और एक चेतावनी देता है, एक त्रुटि नहीं (जैसा मार्को पहले ही टिप्पणियों में इंगित करता है)।

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

फिर, जावा संकलन समय पर सभी सामान्य प्रकार की जानकारी को फेंकता है, इसलिए ई को कास्ट बाइट कोड में मौजूद नहीं है। इस प्रकार, रनटाइम टाइप त्रुटि को भी पहचान नहीं सकता है।

यहां टूटा हुआ क्या अपवाद हैंडलिंग नहीं है, लेकिन टाइप सिस्टम है।

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