2016-12-16 2 views
4

Я прочитал here почему Optional.of() следует использовать более Optional.ofNullable(), но ответ не удовлетворил меня на всех, поэтому я прошу немного иначе:Есть ли настоящая причина использования опции Optional.of()?

Если вы уверены, что ваш метод не возвращает null, зачем вы используете Optional? Насколько мне известно, более или менее единственная цель - напомнить «пользователю метода», что ему, возможно, придется иметь дело с null -значениями. Если ему не нужно иметь дело с -значениями, то почему он должен быть обеспокоен Optional?

Я спрашиваю, потому что я недавно сделал свой служебный слой вместо Опций вместо нулей (в определенных ситуациях). Я использовал Optional.of() и был очень смущен, когда он бросил NullPointer.

образец того, что я сделал:

Optional valueFromDB = getUserById("12"); 
User user = valueFromDB.get(); 

..... 

public Optional<User> getUserById(String id) { 
    //... 
    return Optional.of(userRepository.findOne(id)); // NullPointerException! 
} 

Если нуль не возможно, я не понимаю, почему можно было бы обернуть его в Optional. Чувак в связанном ответе сказал: «Хорошо, если происходит NullPointer, это происходит сразу!» Но я действительно этого хочу? Если единственная цель Optional состоит в том, чтобы напомнить программисту, который получает такой объект, держать в голове null (он должен его развернуть), почему я должен иметь NullPointerException во время упаковки?


Edit: мне нужно изменить этот вопрос, потому что он был отмечен как дубликат, даже если я уже сказал связан вопрос с самого начала. Я также объяснил, почему ответ меня не удовлетворил, но теперь мне нужно отредактировать свой текст с объяснением. Но вот некоторое приложение к тому, что я хочу спросить, так как я получил 5 ответов, и каждый отвечает на другой случай, но ни один полностью не покрыт, что я пытаюсь спросить здесь:

Есть ли причина, что Optional.of (null) невозможно, и они специально добавили Optional.ofNullable() для нулевого случая?

Использование потоков не должно быть проблемой с моей идеей реализации. Я получил много информации из ваших ответов, спасибо за это. Но реальный вопрос до сих пор не ответил, насколько я могу сказать/прочитать/понять. Возможно, мне следовало спросить: «Что, если мы удалим метод Optional.of() и допустим только Optional.ofNullable() в Java 9, возникла бы проблема, кроме обратной совместимости?»

+4

Единственная цель «Необязательно» - четко указать, что результата не может быть. При правильном использовании вам не нужно делать «нулевые» проверки, а yu может выполнять user.ifPresent (doAMethod()) или использовать его в потоках и других API JDK8 без необходимости проверять элементы «null». Поэтому при правильном использовании он может уменьшить количество нулевой проверки в вашем коде. –

+0

@ M.Deinum: 'ifPresent' - это, в основном, нуль-чек. : P Это просто выглядит лучше и удобнее в использовании. Тем не менее, я получаю информацию с потоками, но это не имеет никакого отношения к самому вопросу. Я не задавал вопросы о Optionals, я задал вопрос, если 'Optional.of()' полезна. Извините, если это не ясно. – codepleb

+0

Если ваш метод не предназначен для возврата null, с одной стороны, я согласен, что вы не хотите возвращать 'Optional'. С другой стороны, вы хотите получить информацию, если в один прекрасный день значение, которое вы собираетесь вернуть, является нулевым по ошибке. Для этого я использовал бы добрый старый аргумент 'assert'. –

ответ

1

Я думаю, что вы правы в своем мнении, что не следует использовать опцию, если вы уверены, что всегда имеете возвращаемое значение.

Но Ваш метод не уверен, что он всегда возвращает значение!

Подумайте о вызове getUserById (-1). Существует (как правило) нет пользователя с этим идентификатором, а ваш userRepository вернет null.

Таким образом, в этом случае вы должны использовать опцию. Необязательный.

https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#ofNullable-T-

+2

Да, но вопрос в том, почему 'Optional.of()' существует вообще. – codepleb

6

Вы смешивая API дизайн обоснование со знанием в пределах конкретного кода реализации. Вполне возможно, что метод объявляет о возврате Optional, потому что это значение может отсутствовать, а в определенном месте кода в методе оно, как известно, определенно присутствует. То есть

String content; 
public Optional<String> firstMatch(String pattern) { 
    Matcher m = Pattern.compile(pattern).matcher(content); 
    return m.find()? Optional.of(m.group()): Optional.empty(); 
} 

возвращаемый тип этого метода обозначает String, который может отсутствовать, в то время как в местах кода, создающих Optional экземпляр, известно, присутствует ли или отсутствует значение. Здесь речь идет не о значении null.

Кроме того, в рамках методов потока API findFirst() и findAny(), он будет известен в одной точке, существует ли соответствующий элемент, в то время поддерживая превращение его присутствия на отсутствие в случае сопоставления null элемента явно не поддерживается и предполагается поднять NullPointerException, per specification. Поэтому Optional.of будет использоваться, чтобы вернуть соответствующий элемент, который вы можете легко распознать в трассировки стека при использовании Stream.of((Object)null) .findAny();

+1

См. [Здесь] (http://stackoverflow.com/questions/31696485/why-use-optional-of-over-optional-ofnullable#comment51344170_31696584) для другого примера ... – Holger

1

Angelika Langer говорит, что Optional.ofNullable только удобство-метод, вызывая другие как статические методы из Optional. Он реализован в виде:

return value == null ? empty() : of(value) ; 

Также она говорит, что Optional.ofNullable был добавлен в последнее время к API.

Вот ее текст на немецком языке: http://www.angelikalanger.com/Articles/EffectiveJava/80.Java8.Optional-Result/80.Java8.Optional-Result.html

Так что я хотел бы использовать Optional.of только тогда, когда нуль ошибка, которая должна быть найдена рано. Это то, что сказал Тагир Валеев в: Why use Optional.of over Optional.ofNullable?

+0

@ OleV.V. Спасибо. Я исправил это. –

3

Другая причина использовать Optional.of(value), когда вы знаете, что value не может быть пустым, что если вы хотите сделать дополнительные операции фильтрации по этому Optional.

Например:

public static long getPageSizeFrom(HttpServletRequest request) { 
    return Optional.of(request.getParameter("pageSize")) 
        .filter(StringUtils::isNumeric) 
        .map(Long::valueOf) 
        .filter(page::hasPageSize) 
        .orElse(page::getDefaultPageSize) 
} 
1

Дополнительно есть одна из тех вещей, которые были импортированы из функциональных языков программирования и сбрасывали в круги ОО и процедурные программист without muchbackground explanation ... который причинил много боли и руку скручивание.

Во-первых, быстрая ссылка на блоге (не мной), что значительно помогает очистить воздух на этом: The Design of Optional

Дополнительно связано с функциональными типами программирования как Haskell Maybe. Из-за того, как сильная типизация работает в функциональном программировании, программист на этом языке использовал бы «Может быть, сказать, что значение может быть либо« Кое-что », либо« Ничто ». Здесь есть что-то и ничего. Все, что нуждается в значениях внутри Maybe , имеет для обработки обоих - код просто не будет компилироваться, если он не обрабатывает оба.

Сравните этот сценарий с типичной ситуацией на объектно-ориентированных языках C (Java, C#, C++ и т. Д.), Где объект может иметь значение или быть нулевым. Если методу нужно обрабатывать нулевые параметры как кромку края, вам нужно явно написать этот код - и, будучи ленивыми программистами, мы все, так же часто мы не беспокоимся.

Представьте себе, какое кодирование будет выглядеть, если код не будет компилироваться, если не были случаи null всегда явно обработано. Это довольно близкое сравнение с тем, что происходит при использовании Maybe в функциональных языках.

Когда мы извлекаем языковые функции из функционального программирования, а компилятор ведет себя так, как всегда, и мы кодируем так, как мы всегда имеем ... вы можете видеть, что происходит разрыв.

Отдельно, необязательно, может использоваться как простая подставка для нулевого значения. Поскольку он кажется таким знакомым и является новым, magpie developers склонны использовать его в качестве замены для ситуаций, в которых раньше бы выполнялись проверки на отсутствие. Но, в конце концов, foo.isPresent() действительно так отличается от foo! = Null. Если это единственная разница, это бессмысленно.

И давайте даже не начнем с того, как Необязательный может быть резервным для автобоксинга и распаковки в Java.

Теперь, возвращаясь к конкретному вопросу о конкретном API-интерфейсе Option в Java, сравнивая значениеNullable() vs. of(), лучшее, что я могу решить, это то, что вы, вероятно, не должны использовать те, которые типичны код. Они в основном используются на терминале stream() операций. Вы можете посмотреть код в Optional.of() vs. Optional.ofNullable() и убедиться в том, что единственная разница в том, что из Nullable проверяется, является ли значение нулевым и упорядочивает ситуацию для этой ситуации.

Мой измученный глаз не видит большой пользы для использования Необязательно в Java, если только я не использую потоки Java 8, и я должен это делать. Some будет говорить, что основным преимуществом использования опций как типа для использования без потока является указание, что конкретный параметр является необязательным, то есть логика принимает другой маршрут, если он существует, а не там. Который, опять же, вы можете просто сделать с нулевым. Но я бы сказал, что ментальный багаж, связанный с Факультативным, означает, что для каждого прямого шага, предположительно более сложного кода, вы делаете несколько шагов назад, требуя от людей понять, что Необязательный (в данном конкретном случае) почти полностью косметический. В описанной ситуации я, вероятно, вернусь к использованию нулей и нулевых проверок.

+0

Спасибо за ваше честное мнение.Основная причина их использования (для меня) заключается в том, чтобы напомнить разработчикам, что значение может быть нулевым. Анализ статического кода может в основном сделать то же самое. – codepleb

Смежные вопросы