Unexpected values in Java

Back

You read the documentation of Java and you find the method you were looking for. What are the possible scenarios when running this method?

public static LocalDate parse(CharSequence text);

Documented execution results

The documentation gives 2 explicit answers and an implicit one :

  • The CharSequence represent an actual date, and it returns a non null LocalDate.
  • The CharSequence do not represent a date, the method throws a DateTimeParseException
  • The CharSequence is null. The documentation implicitly says that it would throw a NullPointerException

To be sure to workout all those case, you would have to write something like this:

public void hell(CharSequence str) {
    if (str != null) {
    try {
        LocalDate result = parse(str);
    } catch (DateTimeParseException e) {
        // Exception management
    }
  } else {
    LocalDate result = // ..?
    }
}

Did you find them all ? If not, it’s probably that you don’t know Java as much as you think. We provided yet the answer if the documentation was trustworthy. But we all know that documentation can be wrong ! What else could the method do ?

It could throw a runtime exception that is not documented. This case is not that problematic, because this unexpected behavior would stop your thread execution. Hopefully you already implement a mecanism to cope with runtime exception in your program.

The documentation says that the method would never return a null. But who believes in documentation. You could very well have to deal with a NullPointerException:

LocalDate date = parse("String That Is Parsed As null");
// some other code
date.isBefore(otherDate.plusDays(3)); // throws a Null Pointer Exception

The issue is double here. Firstly, the stack trace will indicate the line of the NullPointerException but not the expression it evaluated. You cannot determine if date or otherDate is the cause of the exception without debugging. The other issue is that the date can be propagated to other methods and create a time bomb in your code. The further the value is propagated the more difficult the root cause analysis.

Mitigating code would be something like:

public void hell(CharSequence str) {
    if (str != null) {
    try {
        LocalDate result = parse(str);
      if (result == null) {
        result = // ..?
      }
    } catch (DateTimeParseException e) {
        // Exception management
    }
  } else {
    LocalDate result = // ..?
    }
}

There are no real long term solution to this. When developing in Java, any expression can be null. You can use tools to analyze your code, but if your program depends on reflection, you will never be sure. You need to accept this, and prepare for long and difficult analysis.

The last unexpected value is not a value: what if the method does never return? This case doesn’t have a name in Java, so I’ll use the Haskell vocabulary: the Bottom or |. What can we do against that? Nothing, definitely nothing. You would usually mitigate such problems by limiting the time tasks can take in your program.

There’s no escape for software hell. Other more strict languages might help you by getting rid of worst cases, but in the end, only one thing count: how clearly you’ve expressed your needs through the code.


Send your comments on twitter or by mail