The best way to deal with this by a substantial margin is to simply not have uninitialized variables, ever, which means you don't need null in the first place (you can replace the functionality with optionals if you really want to, but usually it's not necessary). When I write Java, I declare fields final wherever possible for this and other reasons.
Final is a useful keyword -- a way to make the compiler flag up risky code. :)
The problem (the rest of the time), though, is that if you're writing object-oriented code, some values are simply null. Some data points are unknown, or some properties won't have values for some instances.
If you create an new object but it hasn't been persisted yet, it has a null ID.
If you're working with Categories (of something), some may have a parentCategory and some may not (null).
You can set a placeholder of some kind -- e.g., "-1" means no ID, NO_PARENT is a special Category to return from getParentCategory() if there's no parent, etc.. But then you still need extra code to handle these not-actually-valid values, and when your code is bad, instead of fast-failing with a NullPointerException... things will work, but weirdly. You'll get more confusing errors, further away from the actual bad code.
The Apache Commons way to deal with null is something of a hack, but it works -- library methods for common actions with built-in null handling.
E.g., StringUtils.isBlank(s) is true if s is null, or empty, or only whitespace.
ObjectUtils.isEquals(o1, o2) is true if both are null, false if only one is null, or true if o1.equals(o2).
CollectionUtils.isEmpty(c) returns true if the collection is null, or empty.
I haven't much explored other OO-based approaches to null that are less annoying than Java's handling -- so I'm always curious to hear about smarter approaches.
OP mentioned one of the other approaches..."Optional". An `Optional<String>` will be a non-null reference to either a present value, or an absent value. It's really just modelling null at a non-syntax level, and encourages checking whether there is a value explicitly (i.e. it's self documenting that you need to check if the value is present before using it).
Proponents of Optional will then say that every non-Optional reference must never be null, through static/runtime assertions (like @Nonnull, checkNotNull(), etc)