Никто не любит NullPointerException! Есть ли способ их избежать? Может быть. .
В этой статье будут обсуждаться следующие технологии
1.Необязательный тип (вновь представленный в Java 8)
2.Класс Objects (оригинал в Java 7)
Необязательный класс в Java 8
что это такое?
1. Новые типы, представленные в Java 8.
2. Он используется как оболочка для объекта указанного типа или для сценариев, в которых объект (ноль) не существует.
Проще говоря, это лучшая альтернатива для обработки нулевых значений (предупреждение: на первый взгляд это может быть не так очевидно)
Основное использование
Это тип (класс) – как же создать экземпляр этого типа?
Просто используйте три статических метода:
Скопируйте код кода следующим образом:
public staticOptional<String> stringOptional(String input) {
вернуть Необязательный.of(вход);
}
Просто и понятно — создайте необязательную обертку, содержащую это значение. Помните: если это значение равно нулю, будет выброшено NPE!
Скопируйте код кода следующим образом:
public staticOptional<String> stringNullableOptional(String input) {
if (!new Random().nextBoolean()) {
ввод = ноль;
}
вернуть Необязательный.ofNullable(вход);
}
Я лично считаю, что так лучше. Таким образом, не будет риска NPE — если входное значение равно нулю, будет возвращен пустой необязательный параметр.
Скопируйте код кода следующим образом:
public staticOptional<String> пустойOptional() {
вернуть Необязательный.пустой();
}
Если вы действительно просто хотите вернуть «нулевое» значение. «Пустое» значение не означает ноль.
Хорошо, а как потреблять/использовать опционально?
Скопируйте код кода следующим образом:
общественная статическая недействительность ConsumerOptional () {
Необязательный<String> обернутый = Необязательный.of("aString");
если (wrapped.isPresent()) {
System.out.println("Получена строка - " + обернутый.get());
}
еще {
System.out.println("Попался!");
}
}
Самый простой способ — проверить, действительно ли оболочка Необязательно имеет значение (с помощью метода isPresent). Вы задаетесь вопросом, какое преимущество это имеет перед использованием if(myObj != null). Не волнуйтесь, я объясню это ясно.
Скопируйте код кода следующим образом:
общественная статическая недействительность ConsumerNullableOptional () {
Строковый ввод = ноль;
если (новый Random().nextBoolean()) {
ввод = "iCanBeNull";
}
Необязательный<String> обернутый = Необязательный.ofNullable(входной);
System.out.println(wrapped.orElse("default"));
}
Вы можете использовать метод orElse, чтобы, если инкапсулированное значение действительно является нулевым значением, вы могли использовать его для возврата значения по умолчанию — его преимущества очевидны. При извлечении реального значения можно избежать заведомо избыточного метода вызова метода ifPresent.
Скопируйте код кода следующим образом:
общественная статическая недействительность ConsumerEmptyOptional () {
Строковый ввод = ноль;
если (новый Random().nextBoolean()) {
ввод = "iCanBeNull";
}
Необязательный<String> обернутый = Необязательный.ofNullable(входной);
System.out.println(wrapped.orElseGet(
() -> {
вернуть «defaultBySupplier»;
}
));
}
Я немного смущен этим. Почему существуют два разных метода для одной и той же цели? orElse и orElseGet, очевидно, могут быть перегружены (с тем же именем, но с разными параметрами).
В любом случае, очевидная разница между этими двумя методами заключается в их параметрах — для этого вы можете использовать лямбда-выражения вместо экземпляров Поставщика (функциональный интерфейс).
Почему использование «Необязательно» лучше, чем обычная проверка на ноль?
1. Самым большим преимуществом использования необязательного является то, что вы можете более четко выразить свое намерение - возврат нулевого значения приведет потребителей в замешательство (когда произойдет NPE), является ли оно возвращенным намеренно, поэтому вам придется проверить javadoc для получения более подробной информации. . Использование необязательного довольно просто.
2. С помощью необязательного вы можете полностью избежать NPE — как упоминалось выше, использование необязательных.ofNullable, orElse и orElseGet может удержать нас от NPE.
Еще один спаситель!
Взгляните на этот фрагмент кода и скопируйте приведенный ниже код:
пакет com.abhirockzz.wordpress.npesaviors;
импортировать java.util.Map;
импортировать java.util.Objects;
публичный класс usingObjects {
String getVal(Map<String, String> aMap, String key) {
вернуть aMap.containsKey(ключ)? aMap.get(ключ): ноль;
}
public static void main(String[] args) {
ИспользованиеОбъектовобъект = новый ИспользованиеОбъектов();
obj.getVal(ноль, «пустышка»);
}
}
Какой из них может быть пустым?
1.Карта объекта
2. Ключ, используемый для поиска
3. Этот экземпляр вызова метода
Если выбран NPE, как мы можем определить, какой из них равен нулю?
Скопируйте код кода следующим образом:
пакет com.abhirockzz.wordpress.npesaviors;
импортировать java.util.Map;
импортировать java.util.Objects;
публичный класс usingObjects {
String getValSafe(Map<String, String> aMap, String key) {
Map<String, String> SafeMap = Objects.requireNonNull(aMap,
«Карта пуста»);
String SafeKey = Objects.requireNonNull(ключ, «Ключ имеет значение NULL»);
вернуть SafeMap.containsKey(safeKey)? SafeMap.get(safeKey): ноль;
}
public static void main(String[] args) {
ИспользованиеОбъектовобъект = новый ИспользованиеОбъектов();
obj.getValSafe(null, «пустышка»);
}
}
метод requireNonNull
1. Если объект не равен нулю, вернуть себя
2. Если значение равно нулю, возвращаемый NPE будет содержать указанное сообщение.
Почему это лучше, чем if(myObj!=null)?
В трассировке стека, которую вы видите, будет четко виден вызов метода Objects.requireNonNull. В сочетании с вашим собственным журналом ошибок это поможет вам быстрее обнаружить проблему. . . По крайней мере, на мой взгляд, это быстрее.
Вы также можете настроить свой собственный валидатор, например реализовать простой валидатор, чтобы гарантировать отсутствие нулевых значений.
Скопируйте код кода следующим образом:
импортировать java.util.Collections;
импортировать java.util.List;
импортировать java.util.Objects;
импортировать java.util.function.Predicate;
общественный класс RandomGist {
public static <T> T requireNonEmpty (объект T, предикат Predicate<T>, String msgToCaller) {
Objects.requireNonNull(объект);
Objects.requireNonNull(предикат);
если (predicate.test(объект)){
выдать новое IllegalArgumentException(msgToCaller);
}
вернуть объект;
}
public static void main(String[] args) {
//Использование 1: пустая строка (намеренно)
Строка с = "";
System.out.println(requireNonEmpty(Objects.requireNonNull(s), (s1) -> s1.isEmpty() , «Моя строка пуста!»));
//Использование 2: пустой список (намеренно)
Список списка = Collections.emptyList();
System.out.println(requireNonEmpty(Objects.requireNonNull(list), (l) -> l.isEmpty(), «Список пуст!»).size());
//Использование 3: пустой пользователь (намеренно)
Пользователь Пользователь = новый Пользователь("");
System.out.println(requireNonEmpty(Objects.requireNonNull(user), (u) -> u.getName().isEmpty(), «Пользователь пуст!»));
}
частный статический класс User {
частное имя строки;
общедоступный пользователь (строковое имя) {
это.имя = имя;
}
публичная строка getName(){
вернуть имя;
}
}
}
Не позволяйте NPE стать проблемой не в том месте. У нас есть множество инструментов, позволяющих лучше справляться с НПЭ и даже полностью их искоренить!