Почему мы можем вызвать .orElse () для Optional.of ()? - PullRequest
1 голос
/ 31 октября 2019

Мне любопытно, почему это можно сделать (по крайней мере, в Java 8):

Optional.of(null).orElse("something");

Optional.of(null) - это в основном гарантированный нулевой указатель. Возможность вызывать .orElse() на нем дает неуклюжему разработчику неожиданные дыры, в которые можно попасть. Я искал вокруг, чтобы увидеть, есть ли какое-либо оправдание этому. Может быть, есть какой-то сценарий, к которому это должно обратиться?

Ответы [ 3 ]

7 голосов
/ 31 октября 2019

Есть языки, в которых есть поддержка проверки на нуль прямо в компиляторе (или даже в более хороших языках, у которых вообще нет такой «вещи») - это записывается в компилятор.

javac - не такой компилятор и, честно говоря, я не хочу, чтобы он стал таким же. Есть языки, в которых есть синтаксис, такой как ! или ? или !? - когда я читаю этот код, он либо кричит мне, либо спрашивает (что-то мое мнение).

Теперь вспомните, что Optional предназначен для возвращаемых типов, поэтому внутри тела вашего метода вы используете цепочку методов Optional. Если вы действительно хотите проверить, является ли что-то нулевым или нет, Objects::requireNonNull - используйте это;если вы не уверены, является ли что-то нулевым или нет, вы можете использовать Optional::ofNullable.

Я знаю и прочитал аргументы для Optional::of и Optional::ofNullable, но до сих пор не знаюМне бы хотелось, чтобы это было только последнее. Но эй, люди не должны все время соглашаться: у нас есть Optional::isEmpty и Optional::isPresent. Это хорошее решение? Я не знаю.

Как и любой другой вызов метода, вы можете передать null в любую ссылку на объект, Optional ничем не отличается. Могут ли они добавить семантику для javac для поддержки только Optional::of и проверки нуля? Вероятно. Сколько людей запросят такую ​​поддержку для , и эту функцию, пожалуйста, ?

7 голосов
/ 31 октября 2019

Вы можете сделать это по той же причине, по которой можете написать ((String) null).length(). Компилятор Java имеет статическую проверку для определенных вещей, таких как безопасность типов, но не проверяет и не отвергает код, который доказуемо выдает NullPointerException. Если это так, код throw new NullPointerException(); также не будет разрешен.

Обычно код, генерирующий исключение, не является ошибкой. Хотя статическая проверка может обнаружить подобные вещи и предупредить об этом, было бы плохо, если бы это была ошибка. Некоторые IDE генерируют свои собственные предупреждения о вероятных ошибках, но вы должны решить, что проверять или не стоит проверять.

Для обнаружения этой вероятной ошибки требуется статическая проверка, разработанная с учетом поведенияOptional.of метод. Авторы Спецификации языка Java приняли решение предупреждать о таких вещах, как небезопасные приведения, но не о чем-либо, что зависит от семантики используемых методов. Одним из преимуществ этого решения является то, что оно означает, что JLS может поддерживаться отдельно от Java Class Library документации.

3 голосов
/ 31 октября 2019
Optional.of(null).orElse();

Очевидно, что приведенный выше код всегда будет вызывать исключение. Но как насчет:

Optional.of(someMethod()).orElse();

с

Object someMethod() { return null; }

Вы, наверное, думаете: конечно, то же самое.

Ну, на самом деле это не так. Что, если подкласс переопределяет someMethod() для возврата значения, отличного от null ?! Таким образом, вы не можете решить в время компиляции , будет ли этот метод всегда возвращать ноль в время выполнения .

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

Суть здесь: люди, определяющие язык, должны определить, что, как они ожидают, будут заботиться компиляторы.

Люди из Java выбрали простой компилятор. Тот, который компилируется быстро и не слишком сложен для реализации. Почему? Потому что компилятор просто избегает слишком сложной проверки.

...