There's some precedent in Kotlin, C# and PHP using a postfix marker for nullability. Overall it seems to work good there. Keep in mind that some types may be complex (e.g. when using generics) so using a keyword for the modifier may cause too much verbosity. Verbose is not the same as readable, even if Java is known to confuse the two.
This reminds me of some discussions about the "weirdness budget". When you introduce some new feature, you want it to stand out and be noticed. But as people get used to it, a terser syntax is fine. Some example are callback syntax in various languages introducing a short-hand form when it got popular, or the move from the `try!` macro to the `?` try operator in Rust. You have to consider a longer time horizon for Java's nullability markers. They may be weird at the start, but I feel that the lighter syntax is a better trade-off when you consider their usage 10 years in the future.
Overall, I feel pretty happy with this proposal given their backwards compatibility requirements. I just wish that it had come earlier so `Optional` could enforce non-nullability of its inner type.
> Keep in mind that some types may be complex (e.g. when using generics)
That's exactly why I'm not fond of the question mark, that already has an overloaded meaning in generics. Foo<Bar>, Foo<?>, Foo<Bar?>, Foo<? extends Bar>, Foo<? extends Bar?> look pretty confusingly similar. One could argue that ? and * were terrible symbols for use in generics in the first place, but that ship has sailed.
I'm sure people (myself included) could easily get used to the syntax, but habituation is not going to stop me from being grumpy :-)
That's a good point, though I would argue that this is caused more by the ? in <? extends Bar> than the ? of the nullable type.
I've always found the "? extends" syntax to be confusing, and I feel like the question mark doesn't even need to be there on a syntax level. I also feel like on a language level, Java shouldn't even need a "? extends Bar", but unfortunately Java's generics system isn't strong enough to work without it.
And then it gets worse, with Foo<?> and Foo<? extends Object> being slightly different, even though it makes no sense at all.
This reminds me of some discussions about the "weirdness budget". When you introduce some new feature, you want it to stand out and be noticed. But as people get used to it, a terser syntax is fine. Some example are callback syntax in various languages introducing a short-hand form when it got popular, or the move from the `try!` macro to the `?` try operator in Rust. You have to consider a longer time horizon for Java's nullability markers. They may be weird at the start, but I feel that the lighter syntax is a better trade-off when you consider their usage 10 years in the future.
Overall, I feel pretty happy with this proposal given their backwards compatibility requirements. I just wish that it had come earlier so `Optional` could enforce non-nullability of its inner type.