I use the termal and I make binaries for my use. I'm not going to try to pipe input through several stages of "java -jar myUtil.jar", even if I bother to clear the hurdles of trying to find and configure the right maven plugin to build a "fat" jar.
Null drives a big hole through whatever you try to achieve with the type system. Need a Key for this Lock? Open the Lock anyway, just find out at runtime that the Key was null, rather than at compile time.
Bizarre omissions from the standard library. What do you do with Sets: Union? Intersect? Nope, write them yourself. Wait for a multiple futures? Write a for-loop. Cancel a future? Forget about it. Wait - better than forgetting about it: include cancel() on the class but make it a no-op.
Non-extensible. Let's say the language designers for some reason didn't put takeWhile into Stream. Can you add it?
No way to avoid mutation in order to avoid non-local reasoning about state. If I submit a list as a parameter or accept a list as a parameter, who else has mutated or will mutate that list.
No transactions. Synchronised blocks don't compose: synchronised get() and synchronised set() do not become synchronised getThenSet();
I'm sick of the 'backward compatibility' at all costs. The 'legacy code' that you're thinking of that you don't want to break was written after any of these problems could have been fixed.
https://docs.gradle.org/current/userguide/distribution_plugi...
> Null drives a big hole through whatever you try to achieve with the type system. Need a Key for this Lock? Open the Lock anyway, just find out at runtime that the Key was null, rather than at compile time.
https://github.com/uber/NullAway and bunch of rest.