„Java 8 Lambda“ funkcija, kuri išmeta išimtį?

Žinau, kaip sukurti nuorodą į metodą su String parametru ir grąžina int , tai yra:

 Function<String, Integer> 

Tačiau tai neveikia, jei funkcija išskiria, pvz., Ji apibrėžiama kaip:

 Integer myMethod(String s) throws IOException 

Kaip nustatyti šią nuorodą?

348
13 авг. nustatė Triton Man 13 rug. 2013-08-13 02:16 '13, 02:16 2013-08-13 02:16
@ 23 atsakymai

Jums reikės atlikti vieną iš šių veiksmų.

  • Jei tai yra jūsų kodas, nustatykite savo funkcinę sąsają, kuri paskelbs išskirtą išimtį.

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

    ir jį naudoti

     void foo (CheckedFunction f) { ... } 
  • Priešingu atveju suvyniokite „ Integer myMethod(String s) metodu, kuris nepareiškia patikrintos išimties:

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

    ir tada

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

    arba

     Function<String, Integer> f = (String t) -> { try { return myMethod(t); } catch(IOException e) { throw new UncheckedIOException(e); } }; 
309
13 авг. atsakymas, kurį pateikė jason rugpjūčio 13 d 2013-08-13 02:33 '13, 2:33 2013-08-13 02:33

Tiesą sakant, galite išplėsti Consumer (ir Function ir pan.) Naudodami naują sąsają, kuri tvarko išimtis - naudodami numatytuosius Java 8 metodus!

Apsvarstykite šią sąsają (praplečia 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; } 

Tada, pavyzdžiui, jei turite sąrašą:

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

Jei norite jį naudoti (pvz., Naudodamiesi „ forEach ) su kai kuriais kodais, kurie išmeta išimtis, tradiciškai nustatytumėte bandymo / sugavimo bloką:

 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); 
border=0

Tačiau su šia nauja sąsaja galite sukurti egzempliorių, naudodami lambda išraišką, ir kompiliatorius nesiskundžia:

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

Arba tiesiog tiesiog nuleiskite jį trumpesniam!

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

Atnaujinti . Atrodo, kad „ Durian“ komunalinės bibliotekos dalis yra labai graži, vadinama „ Klaidos“ , kuri gali būti naudojama siekiant išspręsti šią problemą didesniu lankstumu. Pavyzdžiui, pirmiau pateiktame įgyvendinime aš aiškiai apibrėžiau klaidų tvarkymo politiką ( System.out... arba throw RuntimeException ), o Duriano klaidos leidžia taikyti politiką skraidant naudojant daugybę naudingų metodų. Dėkojame, kad dalinatės , @nedtwigg!.

Pavyzdžio naudojimas:

 list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c))); 
153
02 дек. atsakymas pateikiamas jlb 02 dec. 2014-12-02 17:46 '14, 17:46 2014-12-02 17:46

Manau, kad „Durian“ Errors klasė apima daugelį aukščiau pateiktų pasiūlymų privalumų.

Jei norite įtraukti „Durian“ į savo projektą, galite:

52
14 мая '15 в 22:46 2015-05-14 22:46 atsakymą pateikė Ned Twigg gegužės 14 d., 15 val. 10.46 val. 2015-05-14 22:46

Tai netaikoma „Java“ 8. Bandote surinkti kažką panašaus:

 interface I { void m(); } class C implements I { public void m() throws Exception {} //can't compile } 
23
13 авг. atsakymas, kurį pateikė Assylias 2013-08-13 02:36 '13, 2:36 2013-08-13 02:36

Atsakomybės apribojimas: aš dar nepanaudojau „Java 8“, tiesiog skaito apie tai.

Function<String, Integer> IOException , todėl į jį negalima įterpti throws IOException kodo. Jei skambinate metodu, kuris tikisi Function<String, Integer> , tada lambda, kurį perduodate šiam metodui, negali mesti IOException , periodo. Galite rašyti panašų lambda (manau, kad tai yra lambda sintaksė, nežinoma):

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

Arba, jei metodas, kuriuo perduodate lambda, yra tas, kurį parašėte, galite nustatyti naują funkcinę sąsają ir naudoti ją kaip parametrų tipą vietoj Function<String, Integer> :

 public interface FunctionThatThrowsIOException<I, O> { O apply(I input) throws IOException; } 
11
13 авг. R. R. Nelsono atsakymas rugpjūčio 13 d 2013-08-13 02:30 '13, 2:30 2013-08-13 02:30

Jei nenorite naudoti trečiosios šalies bibliotekos ( Vavr ), galite rašyti

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

Ji taip pat turi vadinamąjį „Try monad“, kuris tvarko klaidas:

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

Daugiau skaitykite čia .

Atsakomybės apribojimas: esu Wavre kūrėjas.

7
22 февр. Atsakymą pateikė Daniel Dietrich vasario 22 d. 2016-02-22 00:52 '16 at 0:52 2016-02-22 00:52

Galite naudoti apeiti.

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

arba

 Function<String, Integer> func2 = s1 -> Unthrow.wrap((s2) -> myMethod(s2), s1); 
6
09 марта '16 в 1:13 2016-03-09 01:13 atsakymas pateikiamas SeregaLBN kovo 09 '16, 13:13 2016-03-09 01:13

Jūs galite.

Prireikus išplėsti @marcg UtilException ir pridedant bendrą <E extends Exception> todėl kompiliatorius priverčia jus vėl pridėti mesti išlygas ir lygiai taip pat, jei iš pradžių būtų galima neįtraukti patikrintų išimčių java 8 gijose.

 public final class LambdaExceptionUtil { @FunctionalInterface public interface Function_WithExceptions<T, R, E extends Exception> { R apply(T t) throws E; }  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 { } } 
5
22 июня '15 в 11:36 2015-06-22 11:36 atsakymą pateikė PaoloC birželio 22 d. 15 val. 11:36 2015-06-22 11:36

Tam galite naudoti ET . ET yra maža „Java 8“ biblioteka, leidžianti konvertuoti / išversti išimtis.

Su ET atrodo taip:

 // 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 egzemplioriai yra saugūs ir gali būti bendrinami tarp kelių komponentų. Jei norite, galite nustatyti daugiau konkrečių išimčių konversijos taisyklių (pvz., FooCheckedException -> BarRuntimeException ). Jei nėra kitų taisyklių, patikrintos išimtys automatiškai konvertuojamos į RuntimeException .

(Atsakomybės apribojimas: esu ET autorius)

3
02 сент. atsakymas duotas micha 02 Sep. 2015-09-02 21:04 '15 , 21:04 2015-09-02 21:04

Tačiau galite sukurti savo funkcinę sąsają, kuri atrodytų taip.

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

tada ją įgyvendinkite su „Lambdas“ arba nuorodomis, kaip parodyta žemiau.

 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"); } } 
3
31 мая '15 в 1:48 2015-05-31 01:48 atsakymą pateikė johnnyO gegužės 31 d. 15 val. 1:48 2015-05-31 01:48

Turėjau šią problemą su Class.forName ir Class.newInstance viduje lambda, todėl aš tiesiog padariau:

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

Lambda vietoj to, kad paskambintumėte į Class.forName („myClass“). newInstance () Aš tiesiog pašaukiau uncheckedNewInstanceForName („myClass“)

3
17 янв. atsakymą Sergio pateikė sausio 17 d. 2015-01-17 15:21 '15 15:21 2015-01-17 15:21

Šis klausimas man taip pat trukdė; todėl sukūriau šį projektą .

Su juo galite:

 final ThrowingFunction<String, Integer> f = yourMethodReferenceHere; 

Iš viso yra 39 JDK apibrėžtos sąsajos, turinčios šį Throwing ekvivalentą; visos jos @FunctionalInterface naudojamos srautuose („ Stream bazė, bet taip pat „ IntStream , „ LongStream ir „ DoubleStream ).

Ir kadangi kiekvienas iš jų plečia savo nesuderinamą kopiją, galite juos tiesiogiai naudoti „lambdas“:

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

Numatytasis elgesys yra tas, kad kai jūsų lambda ThrownByLambdaException išmeta patikrintą išimtį, priežastis yra pasirinkta ThrownByLambdaException reikšmė su patikrinta išimtimi. Todėl galite užfiksuoti ir gauti priežastį.

Galimos ir kitos funkcijos.

3
30 дек. atsakymas pateikiamas fge 30 dec. 2014-12-30 01:00 '15, 1:00 2014-12-30 01:00

Kitas sprendimas, naudojant funkcijų apvalkalą, būtų grąžinti savo rezultato korpuso egzempliorių, tarkim, sėkmę, jei viskas vyko gerai, arba, pavyzdžiui, „Nesėkmė“.

Keletas kodų, kad išsiaiškintumėte dalykus:

 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; } } 

Paprasta parinktis:

 List<Try<Integer>> result = Lists.newArrayList(1, 2, 3).stream(). map(Try.<Integer, Integer>tryOf(i -> someMethodThrowingAnException(i))). collect(Collectors.toList()); 
3
30 янв. Atsakyti yohan Jan 30 2014-01-30 16:37 '14, 16:37 2014-01-30 16:37

Idiomas „ CheckedException mesti leidžia apeiti „Lambda“ išraiškos patikrinimą. „ RuntimeException CheckedException “ neapsiriboja griežtu klaidų tvarkymu.

Jis gali būti naudojamas kaip „ Consumer funkcija, naudojama„ Java “rinkinyje.

Čia yra paprastas ir patobulintas strėlės atsako variantas.

 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); } })); } 

Jis tiesiog suvynioja lambda į retroną. Tai leidžia „ CheckedException atšaukti bet kokią Exception kuri buvo išmesta į jūsų lambda.

 public final class Throwing { private Throwing() {} @Nonnull public static <T> Consumer<T> rethrow(@Nonnull final ThrowingConsumer<T> consumer) { return consumer; }  @SuppressWarnings("unchecked") @Nonnull public static <E extends Throwable> void sneakyThrow(@Nonnull Throwable ex) throws E { throw (E) ex; } } 

Čia rasite visą kodą ir vieneto testus.

2
27 окт. atsakymas suteiktas myui 27 oct. 2017-10-27 05:26 '17, 5:26 am 2017-10-27 05:26

Sukurkite pasirinktinį grąžinimo tipą, kuris propaguos patikrintą išimtį. Tai yra alternatyva sukurti naują sąsają, atspindinčią esamą funkcinę sąsają su nedideliu „išimties išimties“ pakeitimu funkcinės sąsajos metode.

Apibrėžimas

„CheckedValueSupplier“

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

Patikrinta reikšmė

 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); } } } 

Naudojimas

 // Don't use this pattern with FileReader, it 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(); 

Kas vyksta

Įtraukus „išimties išimtį“ kiekvienai JDK funkcinei sąsajai būtų blogiausias DRY principo pažeidimas. Siekiant to išvengti, sukuriama viena funkcinė sąsaja, kuri generuoja patikrintą išimtį ( CheckedValueSupplier ). Tai bus vienintelė funkcinė sąsaja, kuri leidžia patikrinti išimtis. Visos kitos funkcinės sąsajos naudos „ CheckedValueSupplier naudodamos bet kokį kodą, kuris išmeta patikrintą išimtį.

CheckedValueCheckedValue “ rezultatas bus bet kokios logikos, kuri išmeta patikrintą išimtį, vykdymo rezultatas. Tai neleidžia nukreipti patikrintos išimties tol, kol kodas bandys pasiekti vertę, kurioje yra „ CheckedValue pavyzdys.

Problemos, susijusios su šiuo požiūriu.

  • Dabar mes mesti „išimtį“, efektyviai slepiant tam tikrą tipą, kuris buvo iš pradžių išleistas.
  • Mes nežinome, kad išimtis įvyko, kol bus CheckedValue#get() .

Vartotojų ir kt

Kai kurios funkcinės sąsajos (pvz., Consumer ) turi būti tvarkomos skirtingai, nes jos nesuteikia grąžinimo vertės.

Funkcija vietoj vartotojo

Vienas iš būdų yra naudoti funkciją vietoj vartotojo, kuris naudojamas apdorojant temas.

  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 

pumpuoti

Arba galite visada pereiti prie „ RuntimeException . Yra ir kitų atsakymų, įrodančių išimties iš Consumer .

Negalima vartoti.

Paprasčiausiai venkite funkcinių sąsajų ir naudokite kilpą su gera alyva.

2
30 авг. atsakymas pateikiamas justin.hughey 30 rug . 2016-08-30 17:44 '16 at 17:44 2016-08-30 17:44

Yra daug puikių atsiliepimų. Tiesiog bandykite išspręsti problemą iš kitos perspektyvos. Tai tik mano 2 centai, prašau ištaisyti mane, jei kažką suklystu.

„FunctionalInterface“ pasiūlymas nėra gera idėja.

Manau, kad tikriausiai nėra gera idėja priversti IOException išimtis dėl šių priežasčių.

  • Atrodo, kad tai anti-Stream / Lambda šablonas. Visa idėja yra ta, kad skambinantysis nusprendžia, kokį kodą suteikti ir kaip elgtis su išimtimi. Daugeliu atvejų IOException gali būti netaikomas klientui. Pavyzdžiui, jei klientas gauna vertę iš talpyklos / atminties, o ne faktinį I / O.

  • Be to, išimčių tvarkymas sriegiuose tampa tikrai bjaurus. Pavyzdžiui, čia bus mano kodas, jei naudosiu jūsų API

      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; }); 

    Bjaurus, ar ne? Be to, kaip minėjau savo pirmojoje pastraipoje, „doSomeOperation“ metodas gali arba negali mesti „IOException“ (priklausomai nuo kliento / skambintojo įgyvendinimo), bet dėl ​​„FunctionalInterface“ metodo metimo kriterijaus visada turiu rašyti ir bandyti jį sugauti.

Ką daryti, jei tikrai žinau, kad ši API sukelia IOException

  • Tada tikriausiai supainiome FunctionalInterface su tipinėmis sąsajomis. Jei žinote, kad ši API sukels IOException, tuomet greičiausiai žinosite ir kai kuriuos numatytuosius / abstrakčius veiksmus. Manau, kad turėtumėte apibrėžti sąsają ir įdiegti savo biblioteką (su numatytuoju / abstraktuoju įgyvendinimu) taip

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

    Tačiau problema, susijusi su bandomuoju gaudymu, vis dar egzistuoja klientui. Jei naudosiu jūsų API sraute, vis tiek turiu tvarkyti IOException iš bjauraus bandymo gaudymo bloko.

  • Pagal numatytuosius nustatymus pateikite srautui tinkamą 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(); } } 

    Numatytasis metodas priima vartotojo objektą kaip argumentą, kuris bus atsakingas už išimties tvarkymą. Dabar, kliento požiūriu, kodas atrodys taip:

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

    Nėra gero Žinoma, vietoj „Exception :: printStackTrace“ galite naudoti logiką ar kitą apdorojimo logiką.

  • Taip pat galite nustatyti būdą, panašų į https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#exceptionally-java.util.function.Function- . Tai reiškia, kad galite atidaryti kitą metodą, kuriame bus išimtis iš ankstesnio metodo skambučio. Trūkumas yra tas, kad dabar jūs visiškai vykdote savo API, o tai reiškia, kad turite susidoroti su siūlų sauga, ir galiausiai jis taps našumo rezultatu. Tik galimybė apsvarstyti.

2
03 янв. Atsakymas pateikiamas TriCore sausio 03 d 2016-01-03 10:36 '16 at 10:36 2016-01-03 10:36

Pagal nutylėjimą „Java 8“ funkcija neleidžia išskirti išimties ir, kaip siūloma keliuose atsakymuose, yra daug būdų, kaip tai pasiekti, vienas iš būdų:

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

Nustatykite, kaip:

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

Ir pridėkite throws arba try/catch tą pačią išimties iš skambučio metodą.

1
13 февр. Atsakymą pateikė Arpit 13 vasaris. 2017-02-13 11:34 '17 at 11:34 2017-02-13 11:34

Jei nenorite naudoti trečiosios šalies bibliotekos, ciklopas reaguoja , kuriam aš prisidedu, galite rašyti „ FluentFunctions“ API

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

ofChecked priima jOOλ CheckedFunction ir grąžina nuorodą, atsipalaiduotą atgal į standartinę (nepatikrintą) JDK java.util.function.Function.

Arba galite toliau dirbti su užfiksuota funkcija naudodami „FluentFunctions api“!

Pavyzdžiui, jei norite atlikti savo metodą, pakartokite jį iki 5 kartų ir užregistruokite jo būseną, galite rašyti

  FluentFunctions.ofChecked(this::myMethod) .log(s->log.debug(s),e->log.error(e,e.getMessage()) .try(5,1000) .apply("my param"); 
1
24 февр. John McClean atsakymas 24 vasaris 2016-02-24 18:56 '16 at 18:56 2016-02-24 18:56

Ką daryti, kad naudotojui būtų leidžiama suteikti vertę, kurią jis tikrai nori išimties atveju. Taigi, turiu kažką panašaus.

 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; } 

Ir tai galima pavadinti taip:

 defaultIfThrows(child -> child.getID(), null) 
0
30 сент. Atsakymas, kurį pateikė mmounirou 30 rugsėjis 2014-09-30 15:37 '14, 15:37 2014-09-30 15:37

Keli iš siūlomų sprendimų naudoja bendrą argumentą E, kad perduotų išskirtą išimtį.

Paimkite dar vieną žingsnį ir vietoj to, kad išeisite išimties tipą, eikite į Vartotojų tipą, kaip ir ...

 Consumer<E extends Exception> 

Вы можете создать несколько повторно используемых вариантов Consumer<Exception> , которые будут охватывать общие потребности обработки исключений вашего приложения.

0
ответ дан Rodney P. Barbati 12 июня '17 в 19:07 2017-06-12 19:07