Java has sum types and is in the process of getting pattern matching (some basic form is already available, but `case Sphere(Point(int x, var y), var r)` already works in preview).
For sum types, the syntax is like this:
sealed interface Expression permits Add, Mult, Identifier {}
// possibly later
record Add(Expression a, Expression b) extends Expression {}
record Identifier(String name) extends Expression {}
I do like global type inference, but for anything that gets committed I often come to prefer at least Rust’s restriction of top level definitions needing types, as that aligns well with how I would also write Haskell and alia. Java imo made a good decision of only adding optional local inference, anything else would have been too disruptive for Java, given its existing talent pool’s background.