Skip to content

Instantly share code, notes, and snippets.

@bdkosher
Last active July 22, 2018 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bdkosher/9a480591f9134419573d710f48e6e62b to your computer and use it in GitHub Desktop.
Save bdkosher/9a480591f9134419573d710f48e6e62b to your computer and use it in GitHub Desktop.
Examples of when Java's compiler makes me sad

Sad Compiler

Overall, Java's compiler is an impressive piece of software (not nearly as impressive as the JVM, though) that has no doubt saved me from countless hours hunting down runtime issues. Nevertheless, there are times when the compiler makes me sad.

Lack of Flow Typing

if (obj instanceof Foo)  {
	((Foo) obj).foo();
}

Why it's sad: given improvements in the compiler's type inferrence ability, it would seem within reason to support flow-sensitive typing. If the condition that obj is an instance of Foo proves true, this information should "flow" into the if body. But no, the compiler still requires an explicit cast on the object in order to use the methods of the Foo type. If you’re a JVM user desperate for flow-sensitive typing, check out Kotlin (or Ceylon).

The Elusive Switch Default

boolean elusiveSwitchDefault(DayOfWeek day) {
  switch (day) {
    case SUNDAY:
    case MODNAY:
    case TUESDAY:
    case WEDNESDAY:
    case THURSDAY:
    case FRIDAY:
    case SATURDAY:
      return true;
    default:
      return false;
  }
}

Why it's sad Clearly, all possible values of the DayOfWeek enumeration are being accounted for in the case statement, therefore there is never an occassion for the default statement to execute. Why it's not that sad First off, enumerations may change over time. If your switch statement is compiled prior to a new enum value being added, then all of a sudden there is a possibility the default case would execute.

The Impossible Else

int impossibleElse(boolean condition) {
  if (condition) {
    return 1;
  } else if (!condition) {
    return 2;
  } else {
    return 3;
  }
}

Ternary Auto-Unboxing Nastiness

boolean nasty(Object obj) {
  return obj == null ? null : true;
}

Why this is sad? This shouldn't even compile, in my opinion. Clearly one part of the ternary operator evaluates to a primitive--why should it be allowed that the other path be null? Because it does, when the compiler tries to auto un-box the resulting null Boolean into a primitive boolean, null pointer exception hilarity ensures.

The Not-so Default Uncaught Exception Handler

Not a compiler issue per-se, but wanted to throw this in:

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
  @Override
  public void uncaughtException(Thread t, Throwable e) {
    throw new RuntimeException();
  }
});

I didn't realize this until recently, but you can override the default exception handler. The funny thing is, if you throw an Error/Exception from this handler, guess what? The runtime handles it! So yes, there is a default default exception hanlder that handles the exceptions thrown by the default exception handler. Ha!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment