Using Checked exceptions along with java.util.function.Predicate

Viewed 1598

Predicates are an awesome concept introduced since 1.8. The composition (and/or) along with other features they provide really makes life easier.

I have been using them extensively for quite sometime, until recently I got stuck with one of the use-cases with respect to exception handling (for checked exceptions) :

Background : I want my predicate implementations to be able to throw out some checked exceptions, which the caller should be able to catch and act upon accordingly. (Some PredicateExecutionFailedException). Since there is no such exception being thrown in JDK's java.util.Predicate definition, I cannot throw any such exception from my implementation. I feel this is a missing piece which would have given more flexibility to the client calling the predicates. Below is the snippet from JDK 1.8.

@FunctionalInterface
public interface Predicate<T> {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);

    /**
     * Returns a composed predicate that represents a short-circuiting logical
     * AND of this predicate and another.  When evaluating the composed
     * predicate, if this predicate is {@code false}, then the {@code other}
     * predicate is not evaluated.
     *

Question : Is there any workaround? I want to catch only checked exceptions (no RuntimeException should be caught). Not able to get my head around this. Any suggestions are welcome.

2 Answers

There is no specefic parent exception class for Checked exception like we have a specific parent exception for all run time exceptions RuntimeException.class . so may be you can use like below .

try {
//write our business logic 
} catch(RuntimeException e ){
 throw e ;
} catch(Exception e){
 // You can catch only checked exception here now
}   

There can be other ways as well

Methods of subclasses and implementing classes cannot throw more checked exceptions than the methods they override or implement because this would violate the Liskov Substitution Principle. The reason is that according to the interface, calls to accept are not required to handle exceptions, so existing implementations cannot be be substituted by some implementations that would require the caller to handle the exception. The Java compiler enforces this constraint.

The typical solution is to re-map exceptions to an specific subtype of RuntimeException, so that exceptions can be caught polymorphically without the risk of catching things like NullPointerException. This means:

Define your own exception:

class PredicateExecutionFailedException extends RuntimeException {
    /* Implementation */    
}

Map desired exceptions to it in Predicate implementations:

public boolean test(String t)
{
    try {
        /* Something */
    }
    catch( SomeException e ) 
    {
        throw new PredicateExecutionFailedException(e);
    }
}

Then declare the type PredicateExecutionFailedException in catch clauses as appropriate.

Related