Мне нравится, что опционы теперь находятся в стандартной библиотеке Java. Но есть одна основная проблема, с которой я постоянно сталкиваюсь, в которой я не понял, как решить в лучшем (проще всего читать и понимать, красивейший, самый короткий) способ:
Как вернуться из метода, когда опция пуста?
Я ищу общее решение, которое работает для разных комбинаций чисел опций и размеров блоков кода.
В следующих примерах я попытаюсь показать, что я имею в виду:
void m1() {
// When I get an optional:
Optional<String> o = getOptional();
// And want to return if it empty
if (!o.isPresent()) return;
// In the whole rest of the method I have to call Optional.get
// every time I want the value:
System.out.println(o.get());
// Which is pretty ugly and verbose!
}
void m2() {
// If I instead return null if a value is absent:
String s = getNullabe();
if (s == null) return;
// Then I can use the value directly:
System.out.println(s);
}
Этот вопрос касается того, как получить хороший аспект обоих приведенных выше примеров: тип безопасно необязательный и кратность типов с нулевым значением.
Остальные примеры иллюстрируют это больше.
void m3() {
// If I on the other hand want to throw on empty that pretty and compact:
String s = getOptional()
.orElseThrow(IllegalStateException::new);
System.out.println(s);
}
void m4() {
Optional<String> o = getOptional();
if (!o.isPresent()) return;
// I can of course declare a new variable for the un-optionalised string:
String s = o.get();
System.out.println(s);
// But the old variable still remains in scope for the whole method
// which is ugly and annoying.
System.out.println(o.get());
}
void m5() {
// This is compact and maybe pretty in some ways:
getOptional().ifPresent(s -> {
System.out.println(s);
// But the extra level of nesting is annoying and it feels
// wrong to write all the code in a big lambda.
getOtherOptional().ifPresent(i -> {
// Also, more optional values makes it really weird and
// pretty hard to read, while with nullables I would
// get no extra nesting, it would looks good and be
// easy to read.
System.out.println("i: " + i);
// It doesn't work in all cases either way.
});
});
}
Optional<String> getOptional() {
throw new UnsupportedOperationException();
}
Optional<Integer> getOtherOptional() {
throw new UnsupportedOperationException();
}
String getNullabe() {
throw new UnsupportedOperationException();
}
Как я могу вернуться из метода, если необязательный пуст, без необходимости использовать get
в остальной части метода, не объявляя дополнительной переменной и без дополнительных уровней блочного вложения?
Или, если это невозможно, чтобы получить все это, каков наилучший способ справиться с этой ситуацией?