Java 8: Mandatory checked exceptions handling in lambda expressions. Why mandatory, not optional?
Asked Answered
G

9

71

I'm playing with the new lambda features in Java 8, and found that the practices offered by Java 8 are really useful. However, I'm wondering is there a good way to make a work-around for the following scenario. Suppose you have an object pool wrapper that requires some kind of a factory to fill the object pool, for example (using 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);
    }

}

After transforming the functional interface into lambda expression, the code above becomes like that:

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

}

Not so bad indeed, but the checked exception java.sql.SQLException requires a try/catch block inside the lambda. At my company we use two interfaces for long time:

  • IOut<T> that is an equivalent to java.lang.functions.Factory;
  • and a special interface for the cases that usually require checked exceptions propagation: interface IUnsafeOut<T, E extends Throwable> { T out() throws E; }.

Both IOut<T> and IUnsafeOut<T> are supposed to be removed during migration to Java 8, however there is no exact match for IUnsafeOut<T, E>. If the lambda expressions could deal with checked exceptions like they were unchecked, it could be possible to use simply like the following in the constructor above:

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

That looks much cleaner. I see that I can rewrite the ObjectPool super class to accept our IUnsafeOut<T>, but as far as I know, Java 8 is not finished yet, so could be there some changes like:

  • implementing something similar to IUnsafeOut<T, E>? (to be honest, I consider that dirty - the subject must choose what to accept: either Factory or "unsafe factory" that cannot have compatible method signatures)
  • simply ignoring checked exceptions in lambdas, so no need in IUnsafeOut<T, E> surrogates? (why not? e.g. another important change: OpenJDK, that I use, javac now does not require variables and parameters to be declared as final to be captured in an anonymous class [functional interface] or lambda expression)

So the question is generally is: is there a way to bypass checked exceptions in lambdas or is it planned in the future until Java 8 is finally released?


Update 1

Hm-m-m, as far as I understand what we currently have, it seems there is no way at the moment, despite the referenced article is dated from 2010: Brian Goetz explains exception transparency in Java. If nothing changed much in Java 8, this could be considered an answer. Also Brian says that interface ExceptionalCallable<V, E extends Exception> (what I mentioned as IUnsafeOut<T, E extends Throwable> out of our code legacy) is pretty much useless, and I agree with him.

Do I still miss something else?

Globulin answered 26/12, 2012 at 11:32 Comment(5)
For anyone following the evolution of the lambdas API, it's worth noting that java.util.functions.Factory::make is now java.util.function.Supplier::get. You can see an up-to-date version of the API docs at lambdadoc.net, a subsite of the [Lambda FAQ] (lambdafaq.org)Maines
@MauriceNaftalin, thanks for the comment. I currently use OpenJDK 1.8.0-EA.Globulin
one approach is given in this blogEvvy
The exception transparency writeup to which you refer was simply a candidate proposal, which was later deemed to be flawed after examination in greater detail.Ibson
@Evvy the link is brokenBrasserie
R
49

Not sure I really answer your question, but couldn't you simply use something like that?

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);
    }
}
Randee answered 26/12, 2012 at 20:0 Comment(25)
Thanks! Yes, your approach seems to be a possible solution in the terms of current Java 8 features (this also was suggested by Matt in a post comment via Guava Throwables java8blog.com/post/37385501926/… ). It also seems to be the most elegant solution, but, I guess you also agree, that's a little boiler-plate. Brian Goetz in 2010 tried something to solve this problem using something like variadic type parameters, and probably Java will get this fixed somehow, who knows.Globulin
Yet another great example of checked exception abuse. Wrapping the exception in RuntimeException might be necessary in this case, but failing to unwrap it again on the outside defeats the entire point of checked exceptions. Please take the time to read why checked exceptions exist and when they should be used: https://mcmap.net/q/55447/-when-to-choose-checked-and-unchecked-exceptionsLole
@Lole Checked exceptions are an abuse of programmer, not vice versa. They promote boilerplate code, incidental complexity, and downright programming errors. They break program flow, especially because try-catch is a statement and not an expression. Wrapping exceptions is a) a nuisance, b) little more than a hack and work around the basic misdesign.Quantum
99% of real-life program logic requires checked and unchecked exceptions alike to break the current unit of work and have them uniformly handled at the top-level exception barrier. Those rare cases where the exception is a part of regular program logic are not something that the programmer will tend to miss, and would need the compiler to tell him.Quantum
@MarkoTopolnik, I respectfully disagree. Coming from a C world, I can tell you that most programmers ignore error codes returned by functions, even if they're part of the "regular program logic". I get the fact that you don't like any exceptions, be they checked or unchecked, but that doesn't mean the rest of all have to follow suit. As for handling all exceptions at a "top-level exception barrier", it sounds to me like you're just catching unrecoverable exceptions. You cannot do anything meaningful at a high-level with most recoverable exceptions.Lole
@MarkoTopolnik, for example: if a user tries opening a non-existent file it would make no sense to handle it at some "top level exception-barrrier". You'd need to handle it at the deepest level and prompt the user for a new path.Lole
@Lole Your example is precisely that rare case which I mention. On the server side such cases are even less frequent. As for your comparison with C, exceptions -- unlike error codes -- can only be ignored explicitly, with empty catch-blocks. Funnily enough, that's exactly what happens when devs are forced to do something about checked exceptions. Your statement that I don't like exceptions sounds like you're trying to be funny, but I'm sorry for missing the humor.Quantum
@Lole At the exception barrier we handle exceptions which break the unit of work---and most do. If any step that needs to be taken fails, the unit of work has failed as well.Quantum
@MarkoTopolnik, what is rare for you is not rare for others. It could very well be that the exceptions you deal with are unrecoverable or unexpected. That's fine. But there are a whole host of cases where this isn't the case. If you only want to use unchecked exceptions, that is your right. I would point out that server-side applications are much less likely to be interactive than client-side applications, and as such exceptions are much less likely to be recoverable. That said, try developing client-side applications for a couple of years and your experience will be exactly the opposite.Lole
@gili I have extensive experience developing at both sides and, although there is a slight difference, the ratio of all exceptions vs. those that need to be caught early is still very large. For example, user input is validated before acting upon it, and that includes such checks as whether a file exists using file.exists(), which makes a subsequent FileNotFoundException a strange and unexpected occurrence.Quantum
@MarkoTopolnik, allow me to introduce you to the possibility of race conditions and I/O errors when reading a file. It doesn't matter how rare an exception is. It matters that it can and does happen in the wild. Having your program crash because of the WIFI connection went down in mid-read is hardly a formula for writing reliable software. Again, you are free to avoid handling such errors if you wish, but implying that everyone should do the same is a different story.Lole
@Lole Now you have invented your own claim and assigned it to me. Where do I claim the application should crash in the face of an exception? I said the current unit of work will be aborted. Now you tell me, how should the current unit of work continue when the WiFi connection is lost? If you have some heuristics in mind that will keep retrying until the connection is reestablished and so on, then that is indeed an example of a special case where exceptions are handled within the unit of work. For most purposes such heuristics are not worth it and simply aborting is good enough.Quantum
@MarkoTopolnik, I withdraw my comment about the software crashing in the face of the WIFI connection going down. We could have a very interesting debate on this topic, but Stackoverflow's comment system doesn't work well for this kind of discussion (comments are too short, and too asynchronous). Let's agree to disagree for now ;)Lole
@Lole surely this specific example is not recoverable anyway. In pretty much any system I have seen, if DriverManager.getConnection fails, something is seriously wrong. If you're in a webapp, the odds are the configuration is incorrect. If you're in a GUI app, the odds are you're using an embedded database and hard-coding the path. So I would never expect getConnection to throw - yet the API forces us to catch it for no good reason. Checked exceptions may have had a theoretical use case, but their inconsistent application in the JRE has made them worse than useless.Diplomat
@Trejkaz, you're using a strawman argument. If you read #28078 you'll see I highlight SQLException as one of the most abused exceptions around. Checked exceptions have a place, but SQLException is not it.Lole
@Lole A "strawman argument" is an argument where I construct one example of a case where my viewpoint is correct and then use it to imply that my viewpoint is correct. The code fragment above uses SQLException, so I believe that in this situation, I am not using a strawman argument as I did not provide the example. Note that I did not say that checked exceptions are useless. I specifically said that checked exceptions in Java are worse than useless. Which is still correct.Diplomat
@Trejkaz, not all exceptions are SQLException yet you seem to be extrapolate from the abusive usage of SQLException to saying all checked exceptions in Java are "worse than useless". I am saying that the first point does not imply the second point.Lole
@Lole Okay, let's flip this around. Can you even name one checked exception in the JRE which is applied consistently and correctly throughout the JRE? I would be interested in hearing your counter-example, because I have not actually discovered a single one yet. (And anyway, I didn't extrapolate from abusive usage of one exception. I extrapolated from a 15 year experience of running into all the other cases where they couldn't seem to get it right.)Diplomat
@Trejkaz java.io.FileNotFoundException comes to mind. As do any I/O operations where it's reasonable to retry on failure (or ask the user for an alternative file). SQLException typically maps to programming errors, but IOException typically maps to runtime errors outside the programmer's control (and in many cases, these failures are recoverable).Lole
I disagree with that case. When the user enters a file path, it is expected they they can enter an invalid path. Since there is a general rule not use exceptions for normal flow control, in this situation I would check that the file exists before opening it. Therefore, having a FileNotFoundException on constructors of stream classes is just a nuisance to me - a second place I will have to catch.Diplomat
@Trejkaz the problem is that you can't have any guarantee that, after you've checked the file existed and you decide to open it, it still exists. Yo need to take race conditions into account.Randee
@JBNizet Sure, but I would argue that sort of condition to be relatively rare and thus not something I should have to take care of with boilerplate. :(Diplomat
@JBNizet After having checked that "foo.xml" exists, many things can go wrong. The file disappearing is what I'd fear least, there may be problems with missing read permissions, failing disk, invalid content or bugs in the parser... and none of the problems can be really solved. All of them must be handled somehow, and I can't see any outstanding solution for FileNotFoundException (offering the user to open "bar.json" instead doesn't count :D). All of the problems may or may not be still present when you retry.Lorenz
Do you know if this already implemented in Spring / apache commons etc? I realize it's a small piece of code but still :DLumbricoid
It is strange that @JBNizet comes up with a clearly case that proves the point against checked exceptions. If forced to catch an exception after checking for the files existence, many programmers would consume the exception without logging (They DO, I've seen it) when they would have ignored it allowing it to be logged if it had been unchecked. Consuming a single checked exception without handling it can cost more developer time than almost any other problem... I've actually spent a full week tracking one of those that would have taken minutes if it had been unchecked and therefore logged.Tillotson
V
34

In the lambda mailing list this was throughly discussed. As you can see Brian Goetz suggested there that the alternative is to write your own combinator:

Or you could write your own trivial combinator:

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

You can write it once, in less that the time it took to write your original e-mail. And similarly once for each kind of SAM you use.

I'd rather we look at this as "glass 99% full" rather than the alternative. Not all problems require new language features as solutions. (Not to mention that new language features always causes new problems.)

In those days the Consumer interface was called Block.

I think this corresponds with JB Nizet's answer.

Later Brian explains why this was designed this way (the reason of problem)

Yes, you'd have to provide your own exceptional SAMs. But then lambda conversion would work fine with them.

The EG discussed additional language and library support for this problem, and in the end felt that this was a bad cost/benefit tradeoff.

Library-based solutions cause a 2x explosion in SAM types (exceptional vs not), which interact badly with existing combinatorial explosions for primitive specialization.

The available language-based solutions were losers from a complexity/value tradeoff. Though there are some alternative solutions we are going to continue to explore -- though clearly not for 8 and probably not for 9 either.

In the meantime, you have the tools to do what you want. I get that you prefer we provide that last mile for you (and, secondarily, your request is really a thinly-veiled request for "why don't you just give up on checked exceptions already"), but I think the current state lets you get your job done.

Vermeil answered 27/3, 2014 at 13:59 Comment(6)
Thanks for the reply. Frankly speaking, I hoped that lambda expressions will be checked-exceptions-friendly, and the universe of checked exceptions will pass by lambdas since they are purely a compiler-driven feature. But no luck.Globulin
@LyubomyrShaydariv I think the expert group struggled with several design issues. The need, requirement or constraint to keep backwards compatibility made things difficult, then we have other important issues like the lack of value types, type erasure and checked exceptions. If Java had the first and lacked of the other two the design of JDK 8 would have been very different. So, we all must understand that it was a difficult problem with lots of tradeoffs and the EG had to draw a line somewhere and make a decision. That may not always pleases us, but surely there will be workarounds suggested.Vermeil
Yes, but lacking both value types and true generics is caused with JVM legacy, despite the checked exceptions do not exist in runtime, and they are purely compiler-driven. Kotlin or Xtend do not have checked exceptions, so they do not force to catch an IOException, for example. For me, it's still not yet clear why the design team doesn't allow to omit the checked exceptions in lambda expressions. It would be nice to have an example scenario where omitting a checked exception in a lambda expression might break the expectations.Globulin
@LyubomyrShaydariv A functional interface is just like any other interface. You can implement it through a lambda expression or manually. If you would throw a checked exception within the implementation of an interface method that does not declare to throw that exception you are breaking the semantics of the programming language. You are throwing an exception not expected by the code dealing with implementations of the interface. I do not see that is OK. I will need a more elaborate example of your proposition for it to make sense to me. Maybe you should create another discussion for that.Vermeil
Well, so the only thing I currently see, if lambda expressions were checked-exceptions-friendly, is: try { iDontHaveThrowsDeclared(x -> someIOOperation(x)) } catch ( IOException ) { ... } won't compile, because IOException in the catch block is known to be a checked one and the iDontHaveThrowsDeclareddoesn't have a throws clause. So yes, it breaks.Globulin
@EdwinDalorzo, to the user a Lambda Expression is like it does not have a function body, it is like it runs completely within the context of where the lambda expression is written. For the same reason, it seems natural to expect that the exception can be handled in that same context, outside the lambda expression, within the method. The problem is that the actual execution can happen at a much - much later point, in a totally different context, maybe as part of an API. We cannot expect an API to handle every conceivable checked Exception. Wrapping in an unchecked exception seems appropriate.Julietjulieta
F
5

September 2015:

You can use ET for this. ET is a small Java 8 library for exception conversion/translation.

With ET you can write:

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

Multi line version:

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

All you need to do before, is creating a new ExceptionTranslator instance:

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

This instance is thread safe an can be shared by multiple components. You can configure more specific exception conversion rules (e.g. FooCheckedException -> BarRuntimeException) if you like. If no other rules are available, checked exceptions are automatically converted to RuntimeException.

(Disclaimer: I am the author of ET)

Fumigant answered 2/9, 2015 at 17:52 Comment(0)
D
5

We developed an internal project in my company that helped us with this. We decided to went public two months ago.

This is what we came up with:

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

}

http://github.com/pivovarit/throwing-function

Doradorado answered 4/4, 2016 at 5:31 Comment(1)
Is this actually the complete implementation? you are lacking any example of how to use it.Tater
S
4

Have you considered using a RuntimeException (unchecked) wrapper class to smuggle the original exception out of the lambda expression, then casting the wrapped exception back to it's original checked exception?

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

Creating your own unique class should prevent any likelihood of mistaking another unchecked exception for the one you wrapped inside your lambda, even if the exception is serialized somewhere in the pipeline before you catch and re-throw it.

Hmm... The only thing I see that's a problem here is that you are doing this inside a constructor with a call to super() which, by law, must be the first statement in your constructor. Does try count as a previous statement? I have this working (without the constructor) in my own code.

Syracuse answered 8/8, 2013 at 20:16 Comment(3)
Thank you for reply. I would really like to prevent explicit try/catching in lambda expressions because try/catch blocks look ugly making the lambdas ugly too. I guess there are at least two reasons of why it cannot work like that so far: 1) the history of Java itself; 2) a method, that's invoked with a lambda expression having methods with throws invocations inside, probably should be "automatically" declared as "throws SomeEx", even if the method is declared without any throws or it declares to throw exception of another type rather than could be propagated from the lambda.Globulin
3) If it could "swallow" checked exceptions, I think, then it might break your expectations for a checked exception or unchecked exception you might expect to catch in any caller outside. For example, you could expect to catch IOException for currently illegal code like list.forEach(p -> outputStream.write(p.hashCode())) (write() throws IOException), but you'd probably couldn't do it, because Iterable.forEach() is not declared as a method throwing IOException, so a compiler cannot know of these intentions. Sometimes checked exceptions are really harmful...Globulin
I agree. It would be overkill to provide a second set of java.util.function classes that declare that they throw a (checked) Exception. Especially since we'd need two versions of every method with a function parameter - one that throws and one that doesn't. That goes a long way toward explaining why Scala doesn't have checked exceptions (only unchecked). Java 8 is a copy of Scala's lambdas with a -> instead of =>. I wonder if Martin Odersky suggested any of this while he was working at Sun? I hope Java 9 includes immutable versions of most of their API classes.Syracuse
H
1

Wrapping the exception in the described way does not work. I tried it and I still get compiler errors, which is actually according to the spec: the lambda expression throws the exception which is incompatible with the target type of the method argument: Callable; call() does not throw it so I can not pass the lambda expression as a Callable.

So basically there is no solution: we are stuck with writing boilerplate. The only thing we can do is voice our opinion that this needs fixing. I think the spec should not just blindly discard a target type based on incompatible thrown exceptions: it should subsequently check whether the thrown incompatible exception is caught or declared as throws in the invoking scope. And for lambda expressions that are not inlined I propose we can mark them as silently throwing checked exception (silent in the sense that the compiler should not check, but the runtime should still catch). let's mark those with => as opposed to -> I know this is not a discussion site, but since this IS the only solution to the question, let yourself be heard and let's change this spec!

Heading answered 13/1, 2013 at 17:54 Comment(4)
The wrapping is described just like it could imitate a checked-exception-less Supplier<T> instead of Callable<T> -- that is a surrogate way and it works for most cases that I was faced with. I personally would change the behavior of lambda expressions / functional interfaces for checked exceptions. But I have doubt that the lambda-dev team will agree to change that behavior for lambda's. Unfortunately Java checked exceptions are good by intention, but harmful in practice. This is similar to wrapping a checked exception into RuntimeException within try/catch in every method.Globulin
Well, there is a way to kind of genericly wrap the checked exception which is slightly more eloborate then described, see my upcoming answer. But still, I agree with you that our programming lives would be better if the compiler would work a bit harder and allow us to throw checked exceptions in our lambdas. As it stands we are deprived of catching specific checked exceptions that occur there, forcing us into ugly cumbersome coding. yuck!Heading
By the way, you can try to suggest your idea for simplified checked exceptions handling to lambda-dev team via their mailing list. If they approve your email (not idea itself) -- you might know their pros and cons for changing the spec, and probably personal ideas and thoughts by Brian Goetz too.Globulin
Thank you for the tip. I tried that actually, but the suggestion has completely been ignored. The reactions of contributions made regarding checked exceptions don't look too positive. Nevertheless I hope that people that share these concerns speak out, while there is still some time to repair it. The java lambda looks so good that this deserves fixing.Heading
S
1

Paguro provides functional interfaces that wrap checked exceptions. I started working on it a few months after you asked your question, so you were probably part of the inspiration for it!

You'll notice that there are only 4 functional interfaces in Paguro vs. the 43 interfaces included with Java 8. That's because Paguro prefers generics to primitives.

Paguro has single-pass transformations built into its immutable collections (copied from Clojure). These transforms are roughly equivalent to Clojure transducers or Java 8 streams, but they accept functional interfaces that wrap checked exceptions. See: the differences between Paguro and Java 8 streams.

Syracuse answered 29/10, 2015 at 19:34 Comment(2)
That's cool stuff, and it's nice to be a part of your inspiration. :) Three years after the post I can't completely refuse the exceptional twins of the standard functional interfaces. I'm pretty sure it's just because I'm too lazy to create yet another business logic interface. I usually never combine them with streams processing, and I think that checked exceptions can be a great option especially for cross-layer communucation.Globulin
I think now, over those years, that my initial question was wrong from the design perspective: why did I want a Supplier instance to be a factory at all? Now I think that that dirty constructor in the post should just delegate something like a IConnectionFactory that declares an SQLException to be thrown just to clearly reveal the intentions of such an interface that might be more or less easily extended in the future.Globulin
M
1

You can throw from your lambdas, they just have to be declared "with your own way" (which makes them, unfortunately, not re-usable in standard JDK code, but hey, we does what we cans).

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

Or the more generic-ized version:

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

ref here. There is also a mention of using "sneakyThrow" to not declare the checked exceptions, but then still throw them. It that hurts my head a bit, maybe an option.

Margarettamargarette answered 19/10, 2017 at 20:0 Comment(0)
E
1

jOOλ is a library that supports wrapping all sorts of functional interfaces throwing checked exceptions into equivalent JDK functional interfaces. For example:

// Wraps the checked exception in an unchecked one:
Supplier<Class<?>> supplier = Unchecked.supplier(() -> Class.forName("com.example.X"));

// Re-throws the checked exception without compile time checking:
Supplier<Class<?>> supplier = Sneaky.supplier(() -> Class.forName("com.example.X"));

I've made some more examples in this blog post here. Disclaimer: I made jOOλ

Evangelist answered 7/10, 2021 at 14:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.