दिलचस्प पोस्ट
कैसे ग्रिडव्यू में हैडर और उपशीर्षक जोड़ने के लिए समस्याओं का संकलन: crt1.o नहीं मिल सकता माउस-ओवर पर सीएसएस और फिर रंग के साथ ग्रेस्केल की छवि? स्थानीय स्तर की उपलब्धता उपलब्ध है या नहीं जैक्सन का उपयोग करने के लिए ArrayList <POJO> JSON को दुबारा बनाना JQuery के साथ एक div की दृश्यमान ऊंचाई प्राप्त करें छवि से पहले और बाद में शीर्षक रेखा जावा JHotDraw में अधिरोहित getActions से संदर्भ मेनू में सबमेनू बनाना रंग 1 और रंग 2 से लेकर एन रंग की ढाल जावा में हीप का आकार बढ़ाएं कस्टम डायलॉग को एनिमेट करें प्रोग्रामिंग पहेली: आप किसी संख्या में Excel कॉलम नाम का अनुवाद कैसे कर सकते हैं? एम्बेडेड Google मानचित्र पर माउस स्क्रॉल व्हील ज़ूम अक्षम करें लॉक (मॉनिटर) एनएटी में आंतरिक कार्यान्वयन जीआईटी – सूचकांक में एक व्यक्तिगत फ़ाइल के SHA1 को ढूंढना

जावा 8 लाम्बा फ़ंक्शंस जो अपवाद फेंकता है?

मुझे पता है कि स्ट्रिंग पैरामीटर वाले किसी पद्धति का संदर्भ कैसे बना सकता है और एक इंट देता है, यह है:

Function<String, Integer> 

हालांकि, यह कार्य नहीं करता यदि फ़ंक्शन एक अपवाद फेंकता है, तो इसे परिभाषित किया गया है:

 Integer myMethod(String s) throws IOException 

मैं इस संदर्भ को कैसे परिभाषित करूंगा?

Solutions Collecting From Web of "जावा 8 लाम्बा फ़ंक्शंस जो अपवाद फेंकता है?"

आपको निम्न में से एक करने की आवश्यकता होगी

  • यदि यह आपका कोड है, तो अपना स्वयं का कार्यात्मक इंटरफ़ेस परिभाषित करें जो चेक अपवाद को घोषित करता है

     @FunctionalInterface public interface CheckedFunction<T, R> { R apply(T t) throws IOException; } 

    और इसका इस्तेमाल करें

     void foo (CheckedFunction f) { ... } 
  • अन्यथा, एक विधि में Integer myMethod(String s) रैप करें जो एक चेक अपवाद घोषित नहीं करता है:

     public Integer myWrappedMethod(String s) { try { return myMethod(s); } catch(IOException e) { throw new UncheckedIOException(e); } } 

    और फिर

     Function<String, Integer> f = (String t) -> myWrappedMethod(t); 

    या

     Function<String, Integer> f = (String t) -> { try { return myMethod(t); } catch(IOException e) { throw new UncheckedIOException(e); } }; 

आप वास्तव में Consumer (और Function आदि) का विस्तार कर सकते हैं, जिसमें एक नया इंटरफ़ेस है जो अपवादों को संभालता है – जावा 8 की डिफ़ॉल्ट विधियों का उपयोग कर रहा है!

इस इंटरफ़ेस पर विचार करें ( Consumer बढ़ाता है):

 @FunctionalInterface public interface ThrowingConsumer<T> extends Consumer<T> { @Override default void accept(final T elem) { try { acceptThrows(elem); } catch (final Exception e) { // Implement your own exception handling logic here.. // For example: System.out.println("handling an exception..."); // Or ... throw new RuntimeException(e); } } void acceptThrows(T elem) throws Exception; } 

फिर, उदाहरण के लिए, यदि आपके पास एक सूची है:

 final List<String> list = Arrays.asList("A", "B", "C"); 

यदि आप कुछ कोड के साथ इसे उपभोग करना चाहते हैं (उदाहरण के लिए, forEach साथ) अपवाद फेंकता है, तो आप पारंपरिक रूप से एक प्रयास / पकड़ ब्लॉक स्थापित करेंगे:

 final Consumer<String> consumer = aps -> { try { // maybe some other code here... throw new Exception("asdas"); } catch (final Exception ex) { System.out.println("handling an exception..."); } }; list.forEach(consumer); 

लेकिन इस नए इंटरफ़ेस के साथ, आप इसे लैम्ब्डा अभिव्यक्ति के साथ इन्स्तांत कर सकते हैं और कंपाइलर शिकायत नहीं करेगा:

 final ThrowingConsumer<String> throwingConsumer = aps -> { // maybe some other code here... throw new Exception("asdas"); }; list.forEach(throwingConsumer); 

या यहां तक ​​कि बस इसे और अधिक संक्षिप्त करने के लिए डाली !:

 list.forEach((ThrowingConsumer<String>) aps -> { // maybe some other code here... throw new Exception("asda"); }); 

अपडेट करें : ऐसा लगता है कि ड्यूरियन नाम की बहुत अच्छी उपयोगिता पुस्तकालय भाग है जो कि इस समस्या को हल करने के लिए बहुत अधिक लचीलेपन के साथ इस्तेमाल किया जा सकता है। उदाहरण के लिए, ऊपर अपने कार्यान्वयन में मैंने स्पष्ट रूप से त्रुटि हैंडलिंग पॉलिसी ( System.out... या throw RuntimeException ) को परिभाषित किया है, जबकि डीरियन की त्रुटियां आपको उपयोगिताओं के एक बड़े सूट के माध्यम से उड़ने पर एक नीति को लागू करने की अनुमति देती हैं। इसे साझा करने के लिए धन्यवाद, @edTwigg!।

नमूना उपयोग:

 list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c))); 

मुझे लगता है कि ड्यूरियन की Errors कक्षाएं विभिन्न सुझावों के ऊपर कई सुझावों को जोड़ती हैं।

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

अपने प्रोजेक्ट में ड्यूरियन को शामिल करने के लिए, आप या तो:

  • इसे jcenter या maven केंद्रीय से com.diffplug.durian:durian:3.3.0 पर ले लो
  • या सिर्फ अपने कोड में सिर्फ दो छोटे वर्ग पेस्ट करें: Throwing.java Errors.java और Errors.java

यह जावा के लिए विशिष्ट नहीं है 8. आप के बराबर कुछ संकलन करने की कोशिश कर रहे हैं:

 interface I { void m(); } class C implements I { public void m() throws Exception {} //can't compile } 

अस्वीकरण: मैंने अभी तक जावा 8 का उपयोग नहीं किया है, केवल इसके बारे में पढ़ें

Function<String, Integer> IOException फेंकता नहीं है, इसलिए आप throws IOException कोई भी कोड नहीं डाल सकते। यदि आप एक विधि कॉल कर रहे हैं जो एक Function<String, Integer> अपेक्षा करता है, तो लैम्ब्डा जिसे आप उस विधि से पास करते हैं IOException , अवधि नहीं फेंक सकते आप या तो इस तरह एक लैम्ब्डा लिख ​​सकते हैं (मुझे लगता है कि यह लैम्ब्डा सिंटैक्स है, निश्चित नहीं है):

 (String s) -> { try { return myMethod(s); } catch (IOException ex) { throw new RuntimeException(ex); // (Or do something else with it...) } } 

या, यदि आप लैम्ब्डा पास कर रहे हैं, तो आप अपने आप को लिखा है, आप एक नया कार्यात्मक इंटरफ़ेस को परिभाषित कर सकते हैं और इसका उपयोग Function<String, Integer> बजाय पैरामीटर प्रकार के रूप में कर सकते हैं: Function<String, Integer> :

 public interface FunctionThatThrowsIOException<I, O> { O apply(I input) throws IOException; } 

आप अनन्त आवरण का उपयोग कर सकते हैं

 Function<String, Integer> func1 = s -> Unthrow.wrap(() -> myMethod(s)); 

या

 Function<String, Integer> func2 = s1 -> Unthrow.wrap((s2) -> myMethod(s2), s1); 

आप ऐसा कर सकते हैं।

@ मर्सीग के यूटिल एक्सपैशन को बढ़ाते हुए और जेनेरिक को जोड़ते समय <E extends Exception> जहां आवश्यक हो: इस तरह, कंपाइलर आपको फिर से UtilException क्लाजों को जोड़ने के लिए मजबूर कर देगा और सब कुछ इस तरह है कि आप जाव 8 की धाराओं पर मूल रूप से अपवादों को चेक कर सकते हैं।

 public final class LambdaExceptionUtil { @FunctionalInterface public interface Function_WithExceptions<T, R, E extends Exception> { R apply(T t) throws E; } /** * .map(rethrowFunction(name -> Class.forName(name))) or .map(rethrowFunction(Class::forName)) */ public static <T, R, E extends Exception> Function<T, R> rethrowFunction(Function_WithExceptions<T, R, E> function) throws E { return t -> { try { return function.apply(t); } catch (Exception exception) { throwActualException(exception); return null; } }; } @SuppressWarnings("unchecked") private static <E extends Exception> void throwActualException(Exception exception) throws E { throw (E) exception; } } public class LambdaExceptionUtilTest { @Test public void testFunction() throws MyTestException { List<Integer> sizes = Stream.of("ciao", "hello").<Integer>map(rethrowFunction(s -> transform(s))).collect(toList()); assertEquals(2, sizes.size()); assertEquals(4, sizes.get(0).intValue()); assertEquals(5, sizes.get(1).intValue()); } private Integer transform(String value) throws MyTestException { if(value==null) { throw new MyTestException(); } return value.length(); } private static class MyTestException extends Exception { } } 

यदि आप किसी तीसरी पार्टी के लिब ( वावर ) को लिखने के लिए कोई बात नहीं मानते हैं

 CheckedFunction1<String, Integer> f = this::myMethod; 

इसमें तथाकथित कोशिश भी है जो त्रुटियों को संभालता है:

 Try(() -> f.apply("test")) // results in a Success(Integer) or Failure(Throwable) .map(i -> ...) // only executed on Success ... 

कृपया यहां अधिक पढ़ें।

अस्वीकरण: मैं वावर का निर्माता हूं

फ़ंक्शन आवरण का उपयोग करने वाला एक अन्य समाधान, या तो आपके परिणाम के आवरण का एक उदाहरण लौटाएगा, सफलता कहता है, अगर सबकुछ ठीक हो गया, या तो एक उदाहरण, विफलता का कहना है

चीजों को स्पष्ट करने के लिए कुछ कोड:

 public interface ThrowableFunction<A, B> { B apply(A a) throws Exception; } public abstract class Try<A> { public static boolean isSuccess(Try tryy) { return tryy instanceof Success; } public static <A, B> Function<A, Try<B>> tryOf(ThrowableFunction<A, B> function) { return a -> { try { B result = function.apply(a); return new Success<B>(result); } catch (Exception e) { return new Failure<>(e); } }; } public abstract boolean isSuccess(); public boolean isError() { return !isSuccess(); } public abstract A getResult(); public abstract Exception getError(); } public class Success<A> extends Try<A> { private final A result; public Success(A result) { this.result = result; } @Override public boolean isSuccess() { return true; } @Override public A getResult() { return result; } @Override public Exception getError() { return new UnsupportedOperationException(); } @Override public boolean equals(Object that) { if(!(that instanceof Success)) { return false; } return Objects.equal(result, ((Success) that).getResult()); } } public class Failure<A> extends Try<A> { private final Exception exception; public Failure(Exception exception) { this.exception = exception; } @Override public boolean isSuccess() { return false; } @Override public A getResult() { throw new UnsupportedOperationException(); } @Override public Exception getError() { return exception; } } 

एक सरल उपयोग का मामला:

 List<Try<Integer>> result = Lists.newArrayList(1, 2, 3).stream(). map(Try.<Integer, Integer>tryOf(i -> someMethodThrowingAnException(i))). collect(Collectors.toList()); 

यह समस्या मुझे भी परेशान कर रही है; यही कारण है कि मैंने इस परियोजना को बनाया है

इसके साथ आप कर सकते हैं:

 final ThrowingFunction<String, Integer> f = yourMethodReferenceHere; 

जेडीके द्वारा परिभाषित 39 इंटरफेस के एक totla हैं जो कि ऐसे Throwing समकक्ष हैं; ये सभी @FunctionalInterface (बेस Stream लेकिन IntStream , LongStream और LongStream ) में इस्तेमाल किए गए सभी @FunctionalInterface हैं।

और जैसा कि उनमें से प्रत्येक अपने बिना फेंकने वाले समकक्ष का विस्तार करते हैं, आप सीधे उन्हें लम्ब्दास में भी इस्तेमाल कर सकते हैं:

 myStringStream.map(f) // <-- works 

डिफ़ॉल्ट व्यवहार यह है कि जब आपके फेंकने वाला लैम्ब्डा एक चेक अपवाद फेंकता है, तो एक ThrownByLambdaException लैम्ब्डा ThrownByLambdaException को कारण के रूप में चेक अपवाद के साथ फेंक दिया जाता है। आप इस पर कब्जा कर सकते हैं और कारण प्राप्त कर सकते हैं।

अन्य सुविधाएं भी उपलब्ध हैं

मुझे क्लास के लिए इस समस्या थी। ForName और कक्षा। एक लैम्ब्डा के अंदर नई, इसलिए मैंने अभी किया:

 public Object uncheckedNewInstanceForName (String name) { try { return Class.forName(name).newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { throw new RuntimeException(e); } } 

कक्षा के लिए कॉल करने के बजाय लैम्ब्डा के अंदर (for "myClass")। NewInstance () मुझे अनचेक किया गया NewInstanceForName ("myClass")

आप फिर भी अपना खुद का फंक्शनल इंटरफेस बना सकते हैं जो नीचे फेंकता है ..

 @FunctionalInterface public interface UseInstance<T, X extends Throwable> { void accept(T instance) throws X; } 

तब इसे लैम्ब्डा या संदर्भों का उपयोग करके इसे नीचे दिखाए अनुसार लागू करें

 import java.io.FileWriter; import java.io.IOException; //lambda expressions and the execute around method (EAM) pattern to //manage resources public class FileWriterEAM { private final FileWriter writer; private FileWriterEAM(final String fileName) throws IOException { writer = new FileWriter(fileName); } private void close() throws IOException { System.out.println("close called automatically..."); writer.close(); } public void writeStuff(final String message) throws IOException { writer.write(message); } //... public static void use(final String fileName, final UseInstance<FileWriterEAM, IOException> block) throws IOException { final FileWriterEAM writerEAM = new FileWriterEAM(fileName); try { block.accept(writerEAM); } finally { writerEAM.close(); } } public static void main(final String[] args) throws IOException { FileWriterEAM.use("eam.txt", writerEAM -> writerEAM.writeStuff("sweet")); FileWriterEAM.use("eam2.txt", writerEAM -> { writerEAM.writeStuff("how"); writerEAM.writeStuff("sweet"); }); FileWriterEAM.use("eam3.txt", FileWriterEAM::writeIt); } void writeIt() throws IOException{ this.writeStuff("How "); this.writeStuff("sweet "); this.writeStuff("it is"); } } 

आप इस के लिए एट का उपयोग कर सकते हैं ईटी अपवाद रूपांतरण / अनुवाद के लिए एक छोटा जावा 8 पुस्तकालय है।

ईटी के साथ यह इस तरह दिखता है:

 // Do this once ExceptionTranslator et = ET.newConfiguration().done(); ... // if your method returns something Function<String, Integer> f = (t) -> et.withReturningTranslation(() -> myMethod(t)); // if your method returns nothing Consumer<String> c = (t) -> et.withTranslation(() -> myMethod(t)); 

ExceptionTranslator उदाहरण हैं थ्रेड सुरक्षित एक कई घटकों द्वारा साझा किया जा सकता है। यदि आपको पसंद है तो आप अधिक विशिष्ट अपवाद रूपांतरण नियमों (जैसे FooCheckedException -> BarRuntimeException ) कॉन्फ़िगर कर सकते हैं यदि कोई अन्य नियम उपलब्ध नहीं हैं, तो जांच की गई अपवाद स्वचालित रूप से RuntimeException परिवर्तित हो जाते हैं।

(अस्वीकरण: मैं ईटी के लेखक हूं)

पहले से ही यहां पोस्ट की गई बहुत बड़ी प्रतिक्रियाएं हैं बस एक अलग परिप्रेक्ष्य के साथ समस्या को हल करने का प्रयास यह सिर्फ मेरे 2 सेंट, कृपया मुझे सही अगर मैं कहीं गलत है।

फंक्शनल इंटरफेस में फेंकता क्लॉज एक अच्छा विचार नहीं है

मुझे लगता है कि यह निम्नलिखित कारणों के कारण IOException को फेंकने के लिए शायद एक अच्छा विचार नहीं है

  • यह मेरे लिए प्रकृति / लैम्ब्डा को एक विरोधी-पैटर्न की तरह दिखता है पूरे विचार यह है कि कॉलर यह तय करेगा कि अपवाद को कैसे संभाल और कैसे संभाल लें। कई परिदृश्यों में, IOException क्लाइंट के लिए लागू नहीं हो सकता है। उदाहरण के लिए, अगर क्लाइंट वास्तविक आई / ओ के बजाय कैश / मेमोरी से मूल्य प्राप्त कर रहा है

  • इसके अलावा, धाराओं में चलने वाले अपवाद वास्तव में घृणित होते हैं उदाहरण के लिए, यहां मेरा कोड ऐसा दिखेगा जैसे मैं आपके एपीआई का उपयोग करता हूं

      acceptMyMethod(s -> { try { Integer i = doSomeOperation(s); return i; } catch (IOException e) { // try catch block because of throws clause // in functional method, even though doSomeOperation // might not be throwing any exception at all. e.printStackTrace(); } return null; }); 

    बदसूरत यह नहीं है? इसके अलावा, जैसा कि मैंने अपने पहले बिंदु में बताया था कि doOomeOperation विधि IOException (क्लाइंट / कॉलर के कार्यान्वयन के आधार पर) फेंक सकता है या नहीं, लेकिन आपके फंक्शनल इंटरफेस विधि में फेंकता क्लॉज के कारण, मुझे हमेशा लिखना होगा पकड़ने की कोशिश।

अगर मैं वास्तव में जानता हूं कि यह एपीआई IOException फेंकता है, तो मुझे क्या करना चाहिए

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

     public interface MyAmazingAPI { Integer myMethod(String s) throws IOException; } 

    लेकिन, ग्राहक के लिए प्रयास-पकड़ समस्या अभी भी मौजूद है। यदि मैं आपकी एपीआई स्ट्रीम में उपयोग करता हूं, तो मुझे अब भी IOException को छिपे हुए प्रयास-कैल ब्लॉक में संभालना होगा।

  • निम्न प्रकार से एक डिफ़ॉल्ट स्ट्रीम-अनुकूल API प्रदान करें

     public interface MyAmazingAPI { Integer myMethod(String s) throws IOException; default Optional<Integer> myMethod(String s, Consumer<? super Exception> exceptionConsumer) { try { return Optional.ofNullable(this.myMethod(s)); } catch (Exception e) { if (exceptionConsumer != null) { exceptionConsumer.accept(e); } else { e.printStackTrace(); } } return Optional.empty(); } } 

    डिफ़ॉल्ट पद्धति उपभोक्ता वस्तु को तर्क के रूप में लेती है, जो अपवाद को संभालने के लिए जिम्मेदार होगी। अब, ग्राहक के दृष्टिकोण से, कोड ऐसा दिखेगा

     strStream.map(str -> amazingAPIs.myMethod(str, Exception::printStackTrace)) .filter(Optional::isPresent) .map(Optional::get).collect(toList()); 

    ठीक है ना? बेशक, अपवाद :: प्रिंटस्टैक्सट्रेस के बजाय लॉगर या अन्य हैंडलिंग लॉजिक का उपयोग किया जा सकता है।

  • आप https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#exceptionally-java.util.function.function- के समान एक विधि का पर्दाफाश कर सकते हैं। जिसका अर्थ है कि आप एक अन्य विधि का पर्दाफाश कर सकते हैं, जिसमें पिछले विधि कॉल से अपवाद होगा। इसका नुकसान यह है कि अब आप अपने एपीआई को स्टेटबल बनाते हैं, जिसका अर्थ है कि आपको थ्रेड-सुरक्षा को संभालना होगा और जो अंततः एक प्रदर्शन हिट बन जाएगा। बस एक विकल्प पर विचार करने के लिए यद्यपि।

एक कस्टम रिटर्न प्रकार बनाएं जो चेक किए गए अपवाद का प्रचार करेगा। यह एक नया इंटरफ़ेस बनाने का एक विकल्प है जो कार्यात्मक इंटरफ़ेस की विधि पर "फेंकता अपवाद" के मामूली संशोधन के साथ मौजूदा फ़ंक्शनल इंटरफ़ेस को दर्पण करता है।

परिभाषा

CheckedValueSupplier

 public static interface CheckedValueSupplier<V> { public V get () throws Exception; } 

CheckedValue

 public class CheckedValue<V> { private final V v; private final Optional<Exception> opt; public Value (V v) { this.v = v; } public Value (Exception e) { this.opt = Optional.of(e); } public V get () throws Exception { if (opt.isPresent()) { throw opt.get(); } return v; } public Optional<Exception> getException () { return opt; } public static <T> CheckedValue<T> returns (T t) { return new CheckedValue<T>(t); } public static <T> CheckedValue<T> rethrows (Exception e) { return new CheckedValue<T>(e); } public static <V> CheckedValue<V> from (CheckedValueSupplier<V> sup) { try { return CheckedValue.returns(sup.get()); } catch (Exception e) { return Result.rethrows(e); } } public static <V> CheckedValue<V> escalates (CheckedValueSupplier<V> sup) { try { return CheckedValue.returns(sup.get()); } catch (Exception e) { throw new RuntimeException(e); } } } 

प्रयोग

 // Don't use this pattern with FileReader, it's meant to be an // example. FileReader is a Closeable resource and as such should // be managed in a try-with-resources block or in another safe // manner that will make sure it is closed properly. // This will not compile as the FileReader constructor throws // an IOException. Function<String, FileReader> sToFr = (fn) -> new FileReader(Paths.get(fn).toFile()); // Alternative, this will compile. Function<String, CheckedValue<FileReader>> sToFr = (fn) -> { return CheckedValue.from ( () -> new FileReader(Paths.get("/home/" + f).toFile())); }; // Single record usage // The call to get() will propagate the checked exception if it exists. FileReader readMe = pToFr.apply("/home/README").get(); // List of records usage List<String> paths = ...; //a list of paths to files Collection<CheckedValue<FileReader>> frs = paths.stream().map(pToFr).collect(Collectors.toList()); // Find out if creation of a file reader failed. boolean anyErrors = frs.stream() .filter(f -> f.getException().isPresent()) .findAny().isPresent(); 

क्या चल रहा है?

JDK में हर कार्यात्मक इंटरफ़ेस को "फेंकता अपवाद" जोड़ना DRY सिद्धांत का एक सबसे जघन्य ढंग से उल्लंघन करेगा। इससे बचने के लिए, एक एकल CheckedValueSupplier इंटरफ़ेस जो चेक किए गए अपवाद को फेंकता है ( CheckedValueSupplier )। यह केवल कार्यात्मक इंटरफ़ेस होगा जो चेक अपवाद को अनुमति देता है। अन्य सभी कार्यात्मक इंटरफेस CheckedValueSupplier को किसी भी कोड को CheckedValueSupplier जो चेक किए गए अपवाद फेंकता है।

CheckedValue वर्ग किसी भी तर्क को निष्पादित करने का परिणाम रखता है जो एक चेक अपवाद को फेंकता है। यह चेक किए गए अपवाद के प्रचार को तब तक रोकता है जब कोड उस मान तक पहुंचने का प्रयास करता है CheckedValue का एक उदाहरण है।

इस दृष्टिकोण के साथ समस्याओं

  • अब हम मूल रूप से फेंक दिया गया विशिष्ट प्रकार को छुपाते हुए "अपवाद" को फेंक रहे हैं।
  • हम अनजान हैं कि जब तक CheckedValue#get() कहा जाता है तब तक अपवाद उत्पन्न होता है।

उपभोक्ता एट अल

कुछ कार्यात्मक इंटरफेस (उदाहरण के लिए Consumer ) को एक अलग तरीके से नियंत्रित किया जाना चाहिए क्योंकि वे रिटर्न वैल्यू नहीं देते हैं।

उपभोक्ता के बदले में फ़ंक्शन

एक दृष्टिकोण उपभोक्ता के बजाय फ़ंक्शन का उपयोग करना है, जो धाराओं को संभालने पर लागू होता है

  List<String> lst = Lists.newArrayList(); // won't compile lst.stream().forEach(e -> throwyMethod(e)); // compiles lst.stream() .map(e -> CheckedValueSupplier.from( () -> {throwyMethod(e); return e;})) .filter(v -> v.getException().isPresent()); //this example may not actually run due to lazy stream behavior 

गहरा बनाना

वैकल्पिक रूप से, आप हमेशा RuntimeException को बढ़ा सकते हैं ऐसे अन्य उत्तर भी हैं जो एक Consumer अंदर से चेक अपवाद को Consumer

उपभोग न करें

बस एक साथ कार्यात्मक इंटरफेस से बचें और पाश के लिए एक अच्छा ऑयल-फ़ैशन का उपयोग करें।

यदि आप तीसरे पक्ष की लाइब्रेरी का उपयोग करते हुए मन नहीं करते हैं, तो साइक्लॉप्स-रिएक्शन के साथ , एक लाइब्रेरी जो मैं योगदान करता हूं, आप लिखने के लिए फ्लुएन्टफंक्शन एपीआई का उपयोग कर सकते हैं

  Function<String, Integer> standardFn = FluentFunctions.ofChecked(this::myMethod); 

की जाँच की एक jOOLAB चेक फंक्शन लेता है और संदर्भ वापस एक मानक (अनियंत्रित) JDK java.util.function.Function करने के लिए नरम हो जाता है।

वैकल्पिक रूप से आप फ्लुअंटफंक्शंस एपीआई के माध्यम से कब्जा किए गए फ़ंक्शन के साथ काम कर सकते हैं!

उदाहरण के लिए, अपनी विधि निष्पादित करने के लिए, इसे 5 गुने तक पुन: प्रयास करना और उस स्थिति को दर्ज करना जिसे आप लिख सकते हैं

  FluentFunctions.ofChecked(this::myMethod) .log(s->log.debug(s),e->log.error(e,e.getMessage()) .try(5,1000) .apply("my param"); 

डिफ़ॉल्ट रूप से, जावा 8 फ़ंक्शन अपवाद छोड़ने की अनुमति नहीं देता है और जैसा कि कई उत्तरों में सुझाव दिया गया है, इसे प्राप्त करने के कई तरीके हैं, एक तरीका है:

 @FunctionalInterface public interface FunctionWithException<T, R, E extends Exception> { R apply(T t) throws E; } 

इस रूप में परिभाषित:

 private FunctionWithException<String, Integer, IOException> myMethod = (str) -> { if ("abc".equals(str)) { throw new IOException(); } return 1; }; 

और कॉलर विधि में समान अपवाद को throws या try/catch

स्नेही फेंक मुहावरे लैम्ब्डा अभिव्यक्ति की चेकेड एक्सपेशेशन को बाईपास करने में सक्षम बनाता है RuntimeException में एक जांच की गई अपवाद को लपेटकर सख्त त्रुटि हैंडलिंग के लिए अच्छा नहीं है।

यह जावा कलेक्शंस में उपयोग किए जाने वाले उपभोक्ता फ़ंक्शन के रूप में उपयोग किया जा सकता है।

यहां जेब के उत्तर का एक सरल और बेहतर संस्करण है।

 import static Throwing.rethrow; @Test public void testRethrow() { thrown.expect(IOException.class); thrown.expectMessage("i=3"); Arrays.asList(1, 2, 3).forEach(rethrow(e -> { int i = e.intValue(); if (i == 3) { throw new IOException("i=" + i); } })); } 

लम्बाडा को फिर से खोलें । यह चेक किया जाता है एक्सक्सेप्शन फेका जाता है जो लैम्ब्डा में हुआ था।

 public final class Throwing { private Throwing() {} @Nonnull public static <T> Consumer<T> rethrow(@Nonnull final ThrowingConsumer<T> consumer) { return consumer; } /** * The compiler sees the signature with the throws T inferred to a RuntimeException type, so it * allows the unchecked exception to propagate. * * http://www.baeldung.com/java-sneaky-throws */ @SuppressWarnings("unchecked") @Nonnull public static <E extends Throwable> void sneakyThrow(@Nonnull Throwable ex) throws E { throw (E) ex; } } 

https://gist.github.com/myui/9722c1301434a3b69cf898ccd9090ff1#file-throwingtest-java-L40 में एक पूरा कोड और इकाई परीक्षण खोजें

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

 public static <T, R> Function<? super T, ? extends R> defaultIfThrows(FunctionThatThrows<? super T, ? extends R> delegate, R defaultValue) { return x -> { try { return delegate.apply(x); } catch (Throwable throwable) { return defaultValue; } }; } @FunctionalInterface public interface FunctionThatThrows<T, R> { R apply(T t) throws Throwable; } 

और फिर इसे कॉल किया जा सकता है:

 defaultIfThrows(child -> child.getID(), null) 

प्रस्तुत समाधानों में से कई ई के एक सामान्य तर्क का उपयोग करते हैं जो अपवाद के प्रकार में फेंक दिया जाता है जो फेंका जाता है।

उस एक कदम को आगे ले, और अपवाद के प्रकार में गुमराते के बजाय अपवाद के प्रकार के उपभोक्ता में पास करें …

 Consumer<E extends Exception> 

आप Consumer<Exception> कई पुन: उपयोग योग्य विविधताएं बना सकते हैं, जो आपके आवेदन की सामान्य अपवाद से निपटने की जरूरतों को कवर करेगा।

मैं कुछ सामान्य करूँगा:

 public interface Lambda { @FunctionalInterface public interface CheckedFunction<T> { T get() throws Exception; } public static <T> T handle(CheckedFunction<T> supplier) { try { return supplier.get(); } catch (Exception exception) { throw new RuntimeException(exception); } } } 

उपयोग:

  Lambda.handle(() -> method()); 
 public void frankTest() { int pageId= -1; List<Book> users= null; try { //Does Not Compile: Object page=DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> new Portal(rw.getInt("id"), "", users.parallelStream().filter(uu -> uu.getVbid() == rw.getString("user_id")).findFirst().get(), rw.getString("name"))); //Compiles: Object page= DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> { try { final Book bk= users.stream().filter(bp -> { String name= null; try { name = rw.getString("name"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return bp.getTitle().equals(name); }).limit(1).collect(Collectors.toList()).get(0); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return new Portal(rw.getInt("id"), "", users.get(0), rw.getString("name")); } ); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }