2

The java.util.Predicate interface contains the test(...) method, whose JavaDoc description states that it [evaluates] this predicate on the given argument and that it [returns] true if the input argument matches the predicate, otherwise false.

Should I take this to mean that test(..) always returns a true or a false and is never allowed to throw an exception? I ask, because the classes from the Collections framework have the concept of "optional operations", where it is explicitly mentioned in the JavaDoc that certain methods might throw UnsupportedOperationException.

First of all, I'm not a Java programmer, I don't work in software development per se, but I use a language that is similar to Java in some respects and I try to follow Java conventions where possible. I've tried searching for resources on the topic, but most of them mention how to throw checked exceptions from stream code.

I'll try to make a contrived example here. Let's say I have a Person class and a Predicate defined like class IsAdult implements Predicate<Object>. Notice that I've used Predicate<Object> and not of Person. Would it be OK to throw an exception if the object being tested is not a Person, for which it's possible to determine whether they are an adult, or should the predicate return false, seeing as how the object that it tested couldn't under any circumstances have been an adult.

Tudor Timi
  • 203
  • 2
  • 7
  • Possible duplicate of [throwing runtime exception in Java application](https://softwareengineering.stackexchange.com/questions/184772/throwing-runtime-exception-in-java-application) – gnat Sep 03 '18 at 14:01

3 Answers3

2

In this specific case, it probably doesn't make sense to throw an exception in most cases, because conceptually whatever you encounter either fulfills the predicate criteria or it doesn't.

If you have expected special cases that are neither "true" nor "false" but have some other meaning that needs to be handled differently, then using a Predicate is the wrong choice, and instead you want to use a Function that outputs e.g. an enum with three or more values.

Basically the main case where you'd want to throw a RuntimeException is when something happens that you didn't expect to happen, something that shows a serious problem (programming error, corrupt data, etc.) and where the only useful response is to abort whatever you were doing and run some special error handling code.

Michael Borgwardt
  • 51,037
  • 13
  • 124
  • 176
0

I guess, it depends. Ideally, there should be no exception, but this isn't always possible. To build upon your example: You could have a class like

class IsKnownToBeAdult implements Predicate<Object> {
    @Overrride
    public boolean test(Object o) {
        return o instanceof Person && ((Person) o).isAdult();
    }
}

but most of the time, this won't be as useful as

/**
  ...
  @throws ClassCastException, if the given object is not a Person.
*/
class IsAdult implements Predicate<Object> {
    @Overrride
    public boolean test(Object o) {
        return ((Person) o).isAdult();
    }
}

Of course, implementing Predicate<Person> is the way to go, whenever possible.


A realistic example would be a predicate needed a database of file access to answer. In this case, you'll get some checked exception and your only sane choice is to wrap it in some RuntimeException.

  • It shouldn't be a plain RuntimeException as its too unspecific.
  • It shouldn't be an UnsupportedOperationException as it doesn't apply (I guess, you never should throw UOE, except in cases covered by the documentation).
  • It could be an IllegalStateException when the problem was caused by a closed session or alike.

In case you anticipate the problem, I'd suggest an own exception class. Otherwise, relying on the general handling of unchecked exceptions should do. Just make sure,

  • you propagate the cause properly for later analysis
  • you store or log the exception somewhere
  • you present a clear and simple message to the user, when necessary
maaartinus
  • 2,633
  • 1
  • 21
  • 29
0

A few points:

1) Exceptions that halt the system, rather then leave it in an undefined state that might compromise its integrity, are a good thing. It's good to avoid these but never ok to disallow them. Yes even on servers.

2) Since 1) is true everywhere it would be annoying to document it everywhere.

3) Caring about unchecked vs checked exceptions is a style choice. In some codebases an unchecked exception is always a sign of a programmer mistake that should be corrected. Other codebases hate the noise checked exceptions leave on method signatures and gleefully avoid ever allowing them. Instead they use unchecked exceptions every time. Conform with your codebase.

4) Because of 3) no one here really knows how seriously to take your methods signature. We'd have to look at your codebase.

candied_orange
  • 102,279
  • 24
  • 197
  • 315