2012-08-13 9 views
17

मैं इस तरह एक विधि है। संकलक मुझे ऐसा करने की अनुमति नहीं देगा क्योंकि मेरी विधि Exception को वहां फेंकने की अनुमति नहीं देती है। लेकिन मुझे अपने परीक्षण (मैं अनचेक Exception फेंक नहीं सकता) के लिए Exception का उप-वर्ग फेंकने की आवश्यकता है। यह स्पष्ट रूप से हैक है लेकिन मुझे अपने परीक्षण के लिए इसकी आवश्यकता है। मैंने EasyMock की कोशिश की लेकिन यह मुझे ऐसा करने की अनुमति नहीं देता है। कोई विचार यह कैसे करना है?अपवाद को कैसे फेंकना है जब आपकी विधि हस्ताक्षर अपवाद को फेंकने की अनुमति नहीं देता है?</p> <pre><code>public void getSomething(){ ... } </code></pre> <p>मैं एक <code>Exception</code><code>getSomething()</code> अंदर फेंक करना चाहते हैं:

धन्यवाद, शॉन गुयेन

+0

तुम कुछ ऐसा करना असंभव है परीक्षण कर रहे हैं। क्यूं कर? – rodrigoap

+0

मैंने लॉजिकल हैंडलर का उपयोग करके साबुन प्रतिक्रिया का नकल करने की कोशिश की। हैंडल मैसेज (लॉजिकल मैसेज कॉन्टेक्स्ट संदर्भ) घोषणा नहीं करता है अपवाद फेंकता है। लेकिन साबुन अंत बिंदु से सभी अपवाद फेंकता अपवादों के उप-वर्ग हैं। मुझे अपनी सेवा प्रतिक्रिया को नकल करने के लिए उन अपवादों को फेंकने की ज़रूरत है। –

+0

यदि आप रुचि रखते हैं तो मेरे संपादन को देखें। –

उत्तर

19

विधि 1:

This post by Alexey Ragozin बताता है कि कैसे एक जेनरिक चाल का उपयोग करने के एक अघोषित जाँच अपवाद फेंकने के लिए। उस पोस्ट से:

public class AnyThrow { 

    public static void throwUnchecked(Throwable e) { 
     AnyThrow.<RuntimeException>throwAny(e); 
    } 

    @SuppressWarnings("unchecked") 
    private static <E extends Throwable> void throwAny(Throwable e) throws E { 
     throw (E)e; 
    } 
} 

चाल throwUnchecked पर निर्भर करता है "झूठ बोल" संकलक है कि प्रकार EthrowAny करने के लिए अपने कॉल के साथ RuntimeException है। चूंकि throwAny को throws E के रूप में घोषित किया गया है, इसलिए संकलक सोचता है कि विशेष कॉल केवल RuntimeException फेंक सकता है। बेशक, चाल throwAny द्वारा मनमाने ढंग से E घोषित कर दिया गया है और अंधेरे से इसे कास्टिंग कर दिया गया है, जिससे कॉलर को यह तय करने की इजाजत मिलती है कि इसका तर्क क्या है - भरोसेमंद डिज़ाइन करते समय भयानक डिज़ाइन। रनटाइम पर, Eerased है और इसका कोई मतलब नहीं है।

जैसा कि आपने देखा है, ऐसी चीज करना एक बड़ा हैक है और आपको इसका उपयोग बहुत अच्छी तरह से करना चाहिए।


विधि 2:

आप भी इस अंत करने के लिए sun.misc.Unsafe उपयोग कर सकते हैं।

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

यह बुला Unsafe.getUnsafe() आम तौर पर एक SecurityException फेंक के रूप में आवश्यक है: सबसे पहले आप एक विधि प्रतिबिंब का उपयोग करता है कि वर्ग के उदाहरण वापस जाने के लिए लागू करना चाहिए। एक बार जब आप Unsafe का उदाहरण है कि आप अपने भयानक क्षमताओं का उपयोग करने के लिए रखा जा सकता है:

Unsafe unsafe = getUnsafe(); 
unsafe.throwException(new Exception()); 

क्रेडिट पद https://stackoverflow.com/questions/5574241/interesting-uses-of-sun-misc-unsafe पर this answer को जाता है।मैंने सोचा कि मैं पूर्णता के लिए इसका जिक्र करूँगा लेकिन शायद आपके कोड में Unsafe की अनुमति देने के बजाय ऊपर की चाल का उपयोग करना बेहतर होगा।


विधि 3:

जुड़ा हुआ जवाब की टिप्पणी में Unsafe, @bestsss points out एक बहुत सरल चाल का उपयोग कर पदावनत विधि Thread.stop(Throwable) उपयोग के बारे में:

Thread.currentThread().stop(new Exception()); 

इस मामले में क्या तुम करोगी @SuppressWarnings("deprecation") का उपयोग करें और एक बार फिर दस्तावेज़ बहुत भयंकर रूप से करें। दोबारा, मैं अपनी (सापेक्ष) सफाई के लिए पहली चाल पसंद करता हूं।

+0

बहुत बहुत धन्यवाद। यह काम करता हैं! –

+0

@PaulBellora आप हमेशा 'कक्षा :: newInstance()' विधि के साथ खेल सकते हैं, जो कुछ भी कर सकता है ctor – emesx

+0

@PaulBellora पहले उदाहरण का परिणाम रनटाइम पर 'ClassCastException' में क्यों नहीं होता है? – Demi

1

जावा अपवाद के दो प्रकार, की जाँच की और अनियंत्रित है। आपको चेक अपवाद घोषित करना होगा, लेकिन आपको अनचेक अपवादों की घोषणा करने की आवश्यकता नहीं है।

RuntimeException मूल अनचेक अपवाद है, इसलिए आप इसे घोषित किए बिना फेंक सकते हैं।

public void getSomething(){ 
    throw new RuntimeException("I don't have to be declared in the method header!"); 
} 

एक तरफ ध्यान दें के रूप में, आप शायद नहीं एक कच्चे RuntimeException फेंक, लेकिन अपनी आवश्यकताओं के कुछ अधिक विशिष्ट करने के लिए यह उपवर्ग करना चाहते हैं। RuntimeException के किसी भी उप-वर्ग को भी अनचेक किया जाएगा।

+0

मुझे स्पष्ट नहीं होने के लिए खेद है। मुझे java.lang.Exception (चेक अपवाद) के उप-वर्ग को फेंकने की आवश्यकता है। –

+3

@ सेननगुएन रनटाइम अपवाद अपवाद का उप-वर्ग है। यह जावा में सिर्फ एक विशेष मामला है जहां आपको यह घोषणा करने की आवश्यकता नहीं है कि इसे फेंक दिया जाएगा। – Oleksi

+0

क्षमा करें, फिर से बहुत स्पष्ट नहीं है। मुझे अपवाद की उप-वर्ग है जो चेक अपवाद फेंकने की जरूरत है। मैं रनटाइम अपवाद नहीं फेंक सकता। –

0

मुझे नहीं पता कि आप क्या करने की कोशिश कर रहे थे। आप बस अपनी विधि के अंदर एक अनचेक अपवाद फेंक सकते हैं और फिर नीचे दिए गए उदाहरण में ज्यूनिट का उपयोग करके परीक्षण कर सकते हैं।

public void getSomething() { 
    throw new RuntimeException(); 
} 

JUnit 4 परीक्षण उदाहरण:

@Test 
public void testGetSomething() { 
    try { 
     getSomething(); 
     fail("Expecting RuntimeException!"); 
    } catch (Exception e) { 
     Logger.getLogger("test").info("Exception was caught: " + e.getClass()); 
    } 
} 
संबंधित मुद्दे