दिलचस्प पोस्ट
सेल वैल्यू प्राप्त करें जैसा कि Excel में प्रस्तुत किया गया था दूसरे पृष्ठ पर एक div की सामग्री लोड करें CakePHP JOIN के साथ विधि का पता लगाएं $ (इस) चयनकर्ता के बच्चों को कैसे प्राप्त करें? स्ट्रिंग लीटरल क्या जावा के डिफॉल्ट पैकेज का एक बुरा अभ्यास है? जावास्क्रिप्ट में एक `नल` मान क्यों है? GetManifestResourceNames को कॉल करते समय संसाधन नाम मौजूद है, जबकि GetManifestResourceStream नल देता है? पायथन में, मैं एक स्ट्रिंग कैसे विभाजित कर सकता हूं और अलग-अलग रखता हूं? "गैर-स्थिर विधि को एक स्थिर संदर्भ से संदर्भित नहीं किया जा सकता" त्रुटि कोडकोड का ड्रॉपबॉक्स एपीआई Xcode 4.6.3 में विफल रहता है: "कोड ऑब्जेक्ट बिल्कुल साइन नहीं हुआ है" UITabelbar को एक UILabel जोड़ना MVC, C # में प्रत्येक अनुरोध में कोई विधि चलाएं? एक पढ़ना असंभव स्तर का उपयोग क्यों करें? AJAX प्रतिक्रिया के लिए jQuery AJAX मतदान, AJAX परिणाम या JSON सामग्री पर आधारित हैंडलिंग

जावा 8: लैम्ब्डा एक्सप्रेशंस में हैंडलिंग अनिवार्य है। क्यों अनिवार्य है, वैकल्पिक नहीं?

मैं जावा 8 में नई लैम्ब्डा सुविधाओं के साथ खेल रहा हूं, और पाया कि जावा 8 द्वारा प्रस्तुत प्रथा वास्तव में उपयोगी हैं। हालांकि, मैं सोच रहा हूं कि निम्नलिखित परिदृश्य के लिए काम करने का एक अच्छा तरीका है। मान लीजिए आपके पास ऑब्जेक्ट पूल आवरण है जिसके लिए ऑब्जेक्ट पूल को भरने के लिए किसी प्रकार के फ़ैक्ट्री की आवश्यकता होती है, उदाहरण के लिए ( java.lang.functions.Factory का प्रयोग करके):

 public class JdbcConnectionPool extends ObjectPool<Connection> { public ConnectionPool(int maxConnections, String url) { super(new Factory<Connection>() { @Override public Connection make() { try { return DriverManager.getConnection(url); } catch ( SQLException ex ) { throw new RuntimeException(ex); } } }, maxConnections); } } 

लैम्ब्डा अभिव्यक्ति में कार्यात्मक इंटरफ़ेस को बदलने के बाद, उपरोक्त कोड उस तरह होता है:

 public class JdbcConnectionPool extends ObjectPool<Connection> { public ConnectionPool(int maxConnections, String url) { super(() -> { try { return DriverManager.getConnection(url); } catch ( SQLException ex ) { throw new RuntimeException(ex); } }, maxConnections); } } 

वाकई बहुत बुरा नहीं है, लेकिन चेक अपवाद java.sql.SQLException लिए लैम्ब्डा के अंदर एक try / catch ब्लॉक try आवश्यकता है। मेरी कंपनी में हम लंबे समय के लिए दो इंटरफेस का उपयोग करते हैं:

  • IOut<T> जो java.lang.functions.Factory बराबर है;
  • और उन मामलों के लिए एक विशेष इंटरफ़ेस जिसे आमतौर पर अपवादों की जांच करने की आवश्यकता होती है: interface IUnsafeOut<T, E extends Throwable> { T out() throws E; } interface IUnsafeOut<T, E extends Throwable> { T out() throws E; }

IOut<T> और IUnsafeOut<T> दोनों को जावा 8 पर प्रवास के दौरान हटाया जाना चाहिए, लेकिन IUnsafeOut<T, E> लिए कोई सटीक मेल नहीं है। यदि लैम्ब्डा अभिव्यक्ति चेक अपवादों से निपट सकती है जैसे कि वे अनचेक होते हैं, तो ऊपर की रचनाकारों में निम्नलिखित की तरह उपयोग करना संभव हो सकता है:

 super(() -> DriverManager.getConnection(url), maxConnections); 

यह बहुत साफ दिखता है मुझे लगता है कि मैं IUnsafeOut<T> सुपर क्लास को हमारे IUnsafeOut<T> को स्वीकार करने के लिए फिर से लिख सकता हूं, लेकिन जहां तक ​​मुझे पता है, जावा 8 अभी तक खत्म नहीं हुआ है, तो ऐसा कुछ बदलाव हो सकता है जैसे:

  • IUnsafeOut<T, E> समान कुछ लागू करना? (ईमानदारी से, मुझे लगता है कि गंदे – विषय को चुनना चाहिए कि क्या स्वीकार करना चाहिए: Factory या "असुरक्षित कारखाना" जो संगत विधि हस्ताक्षर नहीं कर सकते हैं)
  • केवल IUnsafeOut<T, E> में IUnsafeOut<T, E> अपवादों की अनदेखी करते हैं, इसलिए IUnsafeOut<T, E> surrogates में कोई ज़रूरत नहीं है? (क्यों नहीं? जैसे कि एक और महत्वपूर्ण परिवर्तन: ओपन जेडीके, जो मैं उपयोग करता हूं, अब javac को एक अनाम वर्ग [कार्यात्मक इंटरफ़ेस] या लैम्ब्डा अभिव्यक्ति में प्राप्त होने वाले final और घोषित पैरामीटर की आवश्यकता नहीं है

तो सवाल आम तौर पर होता है: क्या लैम्ब्डास में अपवादों को बाईपास करने का एक तरीका है या क्या भविष्य में योजना बनाई जायेगी जब तक कि जावा 8 को अंत में रिलीज़ नहीं किया जा सकता?


अपडेट 1

एचएम-एमएम, जहां तक ​​मैं समझता हूं कि वर्तमान में हमारे पास क्या है, इस संदर्भ में, 2010 में संदर्भित लेख के बावजूद फिलहाल कोई रास्ता नहीं है: ब्रायन गेटेज जावा में अपवाद पारदर्शिता बताते हैं यदि जावा 8 में कुछ ज्यादा नहीं बदला है, तो इसका उत्तर एक उत्तर माना जा सकता है। इसके अलावा ब्रायन कहते हैं कि interface ExceptionalCallable<V, E extends Exception> (जो मैंने उल्लेख किया है IUnsafeOut<T, E extends Throwable> हमारे कोड विरासत के बाहर) काफी बेकार है, और मैं उसके साथ सहमत हूं।

क्या मुझे अभी भी कुछ याद आ रहा है?

Solutions Collecting From Web of "जावा 8: लैम्ब्डा एक्सप्रेशंस में हैंडलिंग अनिवार्य है। क्यों अनिवार्य है, वैकल्पिक नहीं?"

निश्चित नहीं है कि मैं वास्तव में आपके प्रश्न का उत्तर देता हूं, लेकिन क्या आप ऐसा कुछ नहीं इस्तेमाल कर सकते हैं?

 public final class SupplierUtils { private SupplierUtils() { } public static <T> Supplier<T> wrap(Callable<T> callable) { return () -> { try { return callable.call(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } }; } } public class JdbcConnectionPool extends ObjectPool<Connection> { public JdbcConnectionPool(int maxConnections, String url) { super(SupplierUtils.wrap(() -> DriverManager.getConnection(url)), maxConnections); } } 

लैम्ब्डा मेलिंग लिस्ट में इस पर चर्चा हुई । जैसा कि आप देख सकते हैं ब्रायन गोएट्ज़ ने सुझाव दिया है कि विकल्प अपने स्वयं के संयोजक को लिखना है:

या आप अपना तुच्छ संयोजक लिख सकते हैं:

 static<T> Supplier<T> exceptionWrappingSupplier(Supplier<T> b) { return e -> { try { b.accept(e); } catch (Exception e) { throw new RuntimeException(e); } }; } 

आप इसे एक बार लिख सकते हैं, कम से कम यह आपके मूल ई-मेल को लिखने के लिए ले गए। और इसी तरह प्रत्येक एसएएम के लिए एक बार आप का उपयोग करें।

मैं इसके बजाय हम इसे "वैकल्पिक रूप से 99% पूर्ण" के रूप में देखते हैं। सभी समस्याओं को नई भाषा सुविधाओं को समाधान के रूप में चुनने की ज़रूरत नहीं है (यह न कि नई भाषा सुविधाओं में हमेशा नई समस्याएं पैदा होती हैं।)

उन दिनों उपभोक्ता इंटरफ़ेस को ब्लॉक कहा जाता था।

मुझे लगता है कि यह जेबी निजेट के उत्तर के साथ मेल खाती है।

बाद में ब्रायन बताते हैं कि ऐसा क्यों बनाया गया था (समस्या का कारण)

हाँ, आपको अपना असाधारण एसएएम प्रदान करना होगा लेकिन फिर लैम्ब्डा रूपांतरण उनके साथ ठीक काम करेगा।

ईजी ने इस समस्या के लिए अतिरिक्त भाषा और पुस्तकालय समर्थन पर चर्चा की, और अंत में यह महसूस हुआ कि यह एक खराब लागत / लाभ व्यापार था

लाइब्रेरी आधारित समाधान एसएएम प्रकारों (असाधारण बनाम नहीं) में 2x विस्फोट का कारण बनता है, जो कि प्राचीन विशेषीकरण के लिए विद्यमान संयोजी विस्फोटों के साथ बुरी तरह से बातचीत करता है।

उपलब्ध भाषा आधारित समाधान एक जटिलता / मूल्य व्यापार से हानि थे यद्यपि कुछ वैकल्पिक समाधान हैं जो हम तलाशने के लिए जारी रहेंगे – हालांकि 8 के लिए स्पष्ट रूप से नहीं है और शायद 9 के लिए भी नहीं।

इस दौरान, आपके पास जो करना चाहते हैं उसके लिए उपकरण हैं। मुझे लगता है कि आप चाहते हैं कि हम आपके लिए उस अंतिम मील प्रदान करें (और, दूसरी ओर, आपका अनुरोध वास्तव में एक कम वांछित अनुरोध है, "आप पहले से ही चेक अपवादों पर क्यों नहीं छोड़ते हैं"), लेकिन मुझे लगता है कि वर्तमान स्थिति आप अपना काम पूरा कर लेते हैं

क्या आपने लैम्ब्डा अभिव्यक्ति के मूल अपवाद को छिपाने के लिए एक रनटाइम एक्स्प्शन (अनचेक) आवरण वर्ग का उपयोग करने पर विचार किया है, फिर लिपटे अपवाद को मूल जाँच अपवाद में वापस लाया है?

 class WrappedSqlException extends RuntimeException { static final long serialVersionUID = 20130808044800000L; public WrappedSqlException(SQLException cause) { super(cause); } public SQLException getSqlException() { return (SQLException) getCause(); } } public ConnectionPool(int maxConnections, String url) throws SQLException { try { super(() -> { try { return DriverManager.getConnection(url); } catch ( SQLException ex ) { throw new WrappedSqlException(ex); } }, maxConnections); } catch (WrappedSqlException wse) { throw wse.getSqlException(); } } 

अपने खुद के अनूठे वर्ग को बनाने से आपको अपने लैम्ब्डा में लिपटे एक के लिए एक और अनियंत्रित अपवाद को मिटाने की कोई संभावना नहीं होनी चाहिए, भले ही अपवाद को पकड़ने और इसे फिर से फेंकने से पहले पाइप लाइन में कहीं भी क्रमबद्ध किया गया हो।

हम्म … केवल एक चीज मैं देख रहा हूं कि यहां एक समस्या है कि आप इसे कंसट्रक्टर के अंदर सुपर () को कॉल करके कर रहे हैं, जो कानून द्वारा आपके कन्स्ट्रक्टर में पहला बयान होना चाहिए। क्या पिछले बयान के रूप में गिनती की try करता है? मेरे पास यह काम है (कन्स्ट्रक्टर के बिना) अपने कोड में।

सितंबर 2015:

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

ईटी के साथ आप लिख सकते हैं:

 super(() -> et.withReturningTranslation(() -> DriverManager.getConnection(url)), maxConnections); 

मल्टी लाइन संस्करण:

 super(() -> { return et.withReturningTranslation(() -> DriverManager.getConnection(url)); }, maxConnections); 

आपको पहले करने की ज़रूरत है, एक नया ExceptionTranslator उदाहरण बना रहा है:

 ExceptionTranslator et = ET.newConfiguration().done(); 

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

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

हमने अपनी कंपनी में एक आंतरिक परियोजना विकसित की जो इस के साथ हमारी सहायता करती है। हमने दो महीने पहले सार्वजनिक रूप से जाने का फैसला किया।

हमें यह ही मिला:

 @FunctionalInterface public interface ThrowingFunction<T,R,E extends Throwable> { R apply(T arg) throws E; /** * @param <T> type * @param <E> checked exception * @return a function that accepts one argument and returns it as a value. */ static <T, E extends Exception> ThrowingFunction<T, T, E> identity() { return t -> t; } /** * @return a Function that returns the result of the given function as an Optional instance. * In case of a failure, empty Optional is returned */ static <T, R, E extends Exception> Function<T, Optional<R>> lifted(ThrowingFunction<T, R, E> f) { Objects.requireNonNull(f); return f.lift(); } static <T, R, E extends Exception> Function<T, R> unchecked(ThrowingFunction<T, R, E> f) { Objects.requireNonNull(f); return f.uncheck(); } default <V> ThrowingFunction<V, R, E> compose(final ThrowingFunction<? super V, ? extends T, E> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } default <V> ThrowingFunction<T, V, E> andThen(final ThrowingFunction<? super R, ? extends V, E> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } /** * @return a Function that returns the result as an Optional instance. In case of a failure, empty Optional is * returned */ default Function<T, Optional<R>> lift() { return t -> { try { return Optional.of(apply(t)); } catch (Throwable e) { return Optional.empty(); } }; } /** * @return a new Function instance which wraps thrown checked exception instance into a RuntimeException */ default Function<T, R> uncheck() { return t -> { try { return apply(t); } catch (final Throwable e) { throw new WrappedException(e); } }; } 

}

https://github.com/TouK/ThrowingFunction/

वर्णित तरीके में अपवाद को लपेटकर काम नहीं करता है मैंने इसे करने की कोशिश की और मुझे अभी भी कंपाइलर त्रुटियां मिलती हैं, जो वास्तव में कल्पना के अनुसार होती हैं: लैम्ब्डा अभिव्यक्ति अपवाद फेंकता है जो विधि तर्क के लक्ष्य प्रकार के साथ असंगत है: कॉल करने योग्य; कॉल () इसे फेंक नहीं करता है इसलिए मैं लैबलडा अभिव्यक्ति को कॉल करने योग्य के रूप में नहीं दे सकता।

तो मूल रूप से कोई समाधान नहीं है: हम बॉयलरप्लेट लिखने के साथ फंस गए हैं। केवल एक चीज है जो हम कर सकते हैं हमारी राय है कि यह फिक्सिंग की जरूरत है मुझे लगता है कि युक्ति को असंगत फेंक किए गए अपवादों के आधार पर केवल एक लक्ष्य प्रकार को आंखों से नहीं छोड़ना चाहिए: इसे बाद में जांचना चाहिए कि क्या फेंक दिया असंगत अपवाद पकड़ा गया है या घोषित के रूप में घोषित किया गया है जो कि आवर्ती क्षेत्र में फेंकता है। और लैम्ब्डा अभिव्यक्तियों के लिए जो इनलाइन नहीं हैं I प्रस्ताव है कि हम उन्हें चुपचाप चुने गए अपवाद (चुप्पी को चुम्बन के रूप में चिह्नित कर सकते हैं कि संकलक को चेक नहीं करना चाहिए, लेकिन रनटाइम अभी भी पकड़ना चाहिए)। चलो उन लोगों को चिह्नित करें जो => के विपरीत -> मुझे पता है कि यह कोई चर्चा साइट नहीं है, लेकिन चूंकि यह सवाल का एकमात्र समाधान है, आपको सुनना चाहिए और इस कल्पना को बदलना चाहिए!

पगुरू कार्यात्मक इंटरफेस प्रदान करता है जो चेक अपवादों को लपेटता है । मैंने आपके प्रश्न पूछने के कुछ महीनों बाद मैंने इसके बारे में काम करना शुरू कर दिया, इसलिए आप शायद इसके लिए प्रेरणा का हिस्सा थे!

आप देखेंगे कि पागुरो में केवल 4 फ़ंक्शनल इंटरफेस हैं, जो जावा 8 के साथ शामिल 43 इंटरफेस हैं। यही कारण है कि पागुरु को प्राथमिकताएं जेनेरिक पसंद हैं।

पागुरु में सिंगल-पास ट्रांसफ़ॉर्मेशन हैं जो अपने अपरिवर्तनीय संग्रह (क्लोज़र से कॉपी किए गए) में निर्मित हैं। ये परिवर्तन लगभग करीब क्लोज़र ट्रांसड्यूसर या जावा 8 धाराओं के बराबर हैं, लेकिन वे कार्यात्मक इंटरफेस स्वीकार करते हैं जो जाँच अपवादों को लपेटते हैं। देखें: Paguro और Java 8 धाराओं के बीच अंतर ।

आप अपने लम्ब्दास से फेंक सकते हैं , उन्हें सिर्फ "अपने तरीके से" घोषित किया जाना है (जो उन्हें दुर्भाग्य से मानक JDK कोड में पुन: प्रयोग करने योग्य नहीं बनाता है, लेकिन हे, हम जो हम करते हैं)।

 @FunctionalInterface public interface SupplierIOException { MyClass get() throws IOException; } 

या अधिक जेनेरिक-आइज्ड संस्करण:

 public interface ThrowingSupplier<T, E extends Exception> { T get() throws E; } 

यहाँ रेफरी जाँच की गई अपवादों को घोषित नहीं करने के लिए "स्नीक टह" का उपयोग करने का भी उल्लेख है, लेकिन तब भी उन्हें फेंक दो। यह मेरे सिर को थोड़ा सा दर्द होता है, शायद एक विकल्प।