Non-nullable types sound great, I wonder if this could be introduced to Java in a backwards-compatible way (I suppose it would follow the same path with introducing explicitly nullable types first, though I guess it could be handled using Optionals?).
This isn't the only way of doing it, depending on your language. Python has a completely different mechanism where a class can start with a directly-accessed "y", but in a later version make it a property. (More than one, actually.) Some languages route all property accesses through something you can hook. Some languages simply automatically do what C# is doing here.
Semantically and abstractly, there's no reason to every not be able to override a property access in later versions like that, because it is so darned useful. Unfortunately, performance wise, it's hard to beat a language that guarantees structure layout and guarantees that x.y can be compiled into a single constant memory load instruction, and unfortunately, you can't just wave "compiler optimization" at the problem and make it go away (considered in isolation this seems like an obvious solution but as usual as it starts interacting with all the other features it gets much harder than the simple cases). The higher performance languages have a strong reason to give people ways to get guaranteed direct struct member accesses.
I haven't developed in Java in a long time, but public instance variables were a no-no when I did for these reasons.
IMHO they make class APIs much cleaner and forward-compatible (on the other hand, if you started with a public member and then need to add a proper setter with some logic, you would break the API).
Also, non-nullable types are a pretty nice way to avoid checking for null every other line of code.
And these are literally just the first couple examples that came to mind.