Зачем нужен Optional и почему над null нельзя выполнить те же действия?
Вы и так можете проверить проверить ссылку на null, без каких-то дополнительных методов и сущностей. Optional здесь явным образом сообщает, что результат метода может существовать (значение), либо не существовать (null) и не даёт получить значение, не сделав выбор, как обработать ситуацию с его отсутствием. Кроме обычного get() есть ещё методы getOrElse(),  позволяющий указать значение по умолчанию, getOrNull(). 
Ещё бывает удобно сначала выполнить цепочку преобразований над Optional при помощи метода map(), а в конце получить значение любым удобным способом и дальше работать с "чистым" объектом ожидаемого типа.
В kotlinе (раз язык не принципиален) на помощь с борьбой с NPE приходят nullable типы. Каждый класс порождает два типа, к примеру для класса Person это будет Person и Person?. В сигнатурах методов можно явно указать, какой из типов допустим. Если Person?, то компилятор вынудит вас обработать случай с приходом null. Так же вы не сможете вернуть из метода null, если объявили в качестве результата тип Person. Программа просто не скомпилируется.  Все ради того, чтобы null не приходил из неожиданных мест, обрабатывался и не ронял программу.
Вы ведь не можете налить борщ в слово "тарелка"? Вам нужен объект - тарелка.
Получается, в мозгу есть тип Optional который в себе соединяет слово (которое по сути не материально = null) и реальный объект/тип... С компилятором гдето +- все тоже самое.
(Немного фривольное объяснение, но думаю натолкнет на нужные мысли)