Home > front end >  Generify Funtional Interfaces for exceptions from a lambda expression and throw them on the signatur
Generify Funtional Interfaces for exceptions from a lambda expression and throw them on the signatur

Time:09-17

Just for the moderators: This is not a duplicate question.

I need some answers in a very diffucult thing: Throwing exceptions from a lambda expression.

I was based in the link: https://www.baeldung.com/java-lambda-exceptions (and a lot of other links, that I don't have to write here), and I made this code WHICH WORKS. I have to say, that only a person who read the link can understand what I am writing.

---- myMethod which throws exceptions -----

boolean myMethod(element, field, filter) {
    // code which throws these: NoSuchMethodException, InvocationTargetException, IllegalAccessException
}

---- Mother method of interest somewhere in my code -----

public <T> List<T> mamaMethod(List<T> list, String field, String filter) {
        return list == null ? null :
                list.stream().filter(myMehtod(element, field, filter)).collect(Collectors.toList());
}
// Here the "myMethod" throws these: NoSuchMethodException, InvocationTargetException, IllegalAccessException

My Solution according to the link

----- My FunctionalInterface ------

@FunctionalInterface
public interface PredicateWith3Exceptions<T, E1 extends Exception, E2 extends Exception, E3 extends Exception> {
    boolean test(T element) throws E1, E2, E3;
}

---- My Wrapper method ----

private <T, E1 extends NoSuchMethodException, E2 extends InvocationTargetException, E3 extends IllegalAccessException>
    Predicate<T> wrapper(PredicateWith3Exceptions<T, E1, E2, E3> predicate) {
        return element -> {
            try {
                return predicate.test(element);
            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        };
}

--- Put all together in mother method ---

public <T> List<T> list mamaMethod(List<T> list, String field, String filter) {
        return list == null ? null :
                list.stream().filter(wrapper(
                                (PredicateWith3Exceptions<T, NoSuchMethodException, InvocationTargetException, IllegalAccessException>)
                                        element -> myMehtod(element, field, filter))).collect(Collectors.toList());
// In the link there is not casting, but my intelliJ accepts it only with casting to PredicateWith3Exceptions
}

The above code works perfectly good. But, my questions:

  1. How can I generify the PredicateWith3Exceptions, to work with any number of exceptions.

  2. The exceptions are caught in the wrapper. I would like them not to be caught, but to be rethrown with throws statement on the mother method like:

public <T> List<T> mamaMethod(...) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
  1. About the RuntimeException... I don't understand why all links I read they have as ultimate solution the RuntimeException. Others make it so specific to CheckedIOException. All these are unchecked exceptions and I don't understand why I have to mute an exception, which will be thrown itself anyway and it will kill my app.

If the above are not understood, I can rewrite the question.

Thanks a lot

CodePudding user response:

After googling I found out that:

Question 1: In java there is no way to make a variable number of generic types.

Question 2: If I don't want to try catch inside the lambda expression, I can catch the RuntimeException exception from the place I revoke this mother method.

Question 3: I should not throw so generic exception. I could throw e.g. a UncheckedIOException, or another unchecked exception that I can create extending the RuntimeException. Although that I personally don't like unchecked exceptions, in this case is mandatory, because the checked will need to be caught where they already are thrown. They cannot be thrown in higher levels with the thrown statement in the mother method's signiture. But in this case, as long as the final user of the mother method does not have a clue about this RuntimeException, he cannot know that he has to catch it. As some links I found this practice is poor programming practice and code smell.

Anyone who can say his opinion on these thoughts he is free to add as answers. I will close this as my answer as a solution.

  • Related