1. Assume parameters aren't null, and then everything breaks and you fix it.
2. Assume ANY object can be null, and check them all, in every single method, and create correct handling in each case. Basically no one does this.
3. Try to figure out which things can be null or not depending on context. Sometimes you are still wrong, and get NPEs. This is what people actually do.
By defensive programming, do you mean #2? Because that kinda sucks compared to just using Optionals.
Yeah, even when using get() with Optional it's a great way to give semantics to the function that require you to stop for a second. Annotations don't really cut it for most IDEs/Lints.
I do option (2) for every parameter in every non-private method in my Java code. I have a template in my IDE to write the check; all I do is invoke the template, type the variable name, and hit enter. I even document the throw in the javadoc comments. It's not hard, and it's the right thing to do.
Defensive programming in the form of checking all parameters and all return values from library methods for null? Sure, good idea. But then you need a way to distinguish between things that should never be null and things that genuinely might not be present. So Optional is one of the pieces you need to enable this kind of style.
Enums don't have (dynamic) data members, do they? Sometimes you want a representation of e.g. "user's email address, or nothing if they haven't set one". More, you want that often enough that it's worth having a single generic way to represent it rather than having to construct a custom NullObject for each case.
The pervasive lack of defensive programming slays me.