I'll leave links for Haskell since the only one of those I've tried and liked personally:
IMO Haskell is the type system you wanted Java to have, with even more strictness. While it's possible to write unsafe haskell, just about everything you will read, and the language itself encourages you to push as many worries as you can to be solved by the type system.
If that doesn't get you excited, there's actually a saying that is mostly true in my experience writing Haskell -- "If it compiles, it works"(tm).
Also Haskell on the JVM if you want to dip your toes in:
- https://github.com/Frege/frege
[EDIT] - If you try to learn haskell you'll inevitably run into the M word which rhymes with Gonad. The best guide I've ever read is @ http://adit.io/posts/2013-04-17-functors,_applicatives,_and_...
BTW, be ye warned: when you start understanding/getting cozy with the concepts introduced by Haskell you'll wish they were everywhere, and they're not. Languages without proper union types will look dumb to you, easy function composition/points free style will be a daily desire, and monadic composition of a bunch of functions will be frustratingly absent/ugly in other languages, not doing errors-as-values will look ironically error-prone.
[EDIT 2] - More relevant to the actual post, how you would do this in Haskell is using the `type` keyword (type aliasing, e.g. `type Email = String`) or the `newtype` keyword, which creates a new type that is basically identical (what the article talks about). Here's some discussion on newtype:
- http://degoes.net/articles/newtypes-suck (this article is good, it describes the premise, promise, shortcomings, and workarounds, forgive the clickbaity title)
- https://www.reddit.com/r/haskell/comments/4jnwjg/why_use_new...