Search code examples
javacoding-stylerefactoring

Is there a short elegant way to write variable providing with exception?


So, I want to write these kind of things for my code, but there's too much code for one variable. How can I use modern Java for solving this problem shorter or cleaner? Moving it in the separate method doesn't solve the problem, because I still need to check the variable for null, which is wordy and adds extra method that used only once. It is possible to use Optionals here? Seems like return prevents this. Maybe there's the way for collapsing this thing into one for many variables like the foo described below? I don't know, just something to make it more readable and clean.

Foo foo;
try {
    foo = FooProvider.getFoo(...);
} catch (FooProvidingException e) {
    System.err.println("Foo exception: " + e.getMessage());
    return;
}
// use foo, maybe in another method (when foo is the field).

I know, this question may be opinionated, but any help would be a valid answer.

Sorry for my poor english and thanks in advance!


Solution

  • What you're asking is not very clear, so I don't know at which extent my answer will be meaningful.

    If I understand well, you have fields of any type (Foo, Bar...) and you would like to instantiate them using whatever kind of provider you wish, which can throw an exception while providing.

    So at first, I don't think that you should return if an exception is thrown by the provider, but rather re-throw it or handle it. Because if you had an exception while getting your Foo and so you actually don't have a Foo, why would you continue (or why wouldn't you try to handle it somehow)?

    Now this said and assuming that re-throwing/handling is taken care of, then I would define a ThrowingSupplier functional interface:

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

    ... and then I would create a static method like this:

    public static <T, E extends Exception> T provide(ThrowingSupplier<T, E> supplier) {
        try {
            return supplier.get();
        } catch (Exception e) {
            System.err.println("Exception: " + e.getMessage());
            throw (E) e;
        }
    }
    

    So at that point, I would be simply calling this utility method every time that I want to execute such kind of operation:

    Foo foo = provide(() -> FooProvider.getFoo(...)); //either creates a Foo, or prints and re-throw a FooProvidingException
    Bar bar = provide(() -> BarProvider.getBar(...)); //either createa a Bar, or prints and re-throw a BarProvidingException
    Integer myInt = provide(() -> 3);
    String myStr = provide(() -> "hello");
    //... and so on
    

    But of course, at least once you'll have to extract the logic. Then it's all about extracting it in a way that it becomes generic and doesn't need to be repeated for each distinct type of object.