Languages such as Swift, Kotlin has a distinction in the reference types — Optional and Non-Optional references or Nullable and Non-Null types — where only an Optional or Nullable type can hold a nil or null reference.
Java SE 8 also has support for Optional, but the difference is that in Swift and Kotlin a normal field cannot hold a null reference. It has to be declared an Optional type to hold a null. Java is not that strict that it allows null reference to normal fields also, but it is possible to write better APIs in Java also using Optional.
All these type systems try their best to avoid the null references — the billion dollar mistake as the inventor of null reference Tony Hoare called it.
If you are switching from a language that doesn’t have Optional — like Java 7 or Objective-C — to a language that supports Optional, chances are that you merely translate all your fields to Optional. But that’s not a very good practice.
It is very important to understand what problem this Optional type solves. The advantage compared to the normal null references is that the Optional types forces you — or the client of your API — to think about the case when the value is not present.
That’s it. By declaring a field as an Optional you declare that it is possible that the field can be empty and it makes the clients of the API handle the empty value case.
Let’s assume there is a class, Customer and it has two fields: customerId and customerName. And for any customer, these two fields cannot be empty, logically.
If you declare these two fields as Optional, you declare that these fields can be empty. And this creates a potential for having a customer object in an invalid state in the runtime — that is a customer object that has empty id or name but which cannot be empty based on your business logics.
Having an object in an invalid state is more dangerous than a Null Pointer Exception as the invalid object will not crash your app but make your app behave in a weird manner and it is very hard to debug the cause.
So think hard before declaring a field as an Optional whether that field can be empty logically. If some fields cannot be null based on your business logics, don’t declare it as an Optional. If you need to declare some field that cannot be null logically as an Optional for some special use-cases, you may first have to think of other possibilities or restructuring your code rather than using Optional as the first choice.
Having every field as Optional references and using safe calls or optional chaining ( bob?.department?.head?.name ) to access the values might avoid you Null Pointer Exceptions in the beginning. But it will bite you in the long run as you might get null values even for the fields that cannot have null value logically and leave the objects in invalid states and worse you have no easy way to figure that out.