Избегать! = Нулевые заявления - PullRequest
3805 голосов
/ 07 ноября 2008

Я использую object != null много, чтобы избежать NullPointerException.

Есть ли хорошая альтернатива этому?

Например:

if (someobject != null) {
    someobject.doCalc();
}

Это позволяет избежать NullPointerException, когда неизвестно, является ли объект null или нет.

Обратите внимание, что принятый ответ может быть устаревшим, см. https://stackoverflow.com/a/2386013/12943 для более позднего подхода.

Ответы [ 62 ]

9 голосов
/ 09 октября 2017

Java 8 представила новый класс Необязательный в пакете java.util.

Преимущества Java 8 Необязательно:

1.) Нулевые проверки не требуются.
2.) Нет больше NullPointerException во время выполнения.
3.) Мы можем разработать чистые и аккуратные API.

Необязательно - Объект-контейнер, который может содержать или не содержать ненулевое значение. Если значение присутствует, isPresent () вернет true, а get () вернет значение.

Более подробную информацию вы найдете здесь: oracle docs: - https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

8 голосов
/ 11 марта 2011

Вы можете использовать FindBugs . У них также есть плагин Eclipse , который помогает вам находить дубликаты нулевых проверок (помимо прочего), но помните, что иногда вам следует выбрать защитное программирование. Есть также Контракты для Java , которые могут быть полезны.

7 голосов
/ 14 ноября 2017

В целом, чтобы избежать заявления

if (object != null) {
    ....
}
  1. начиная с Java 7 вы можете использовать Objects методы:

    Objects.isNull (объект)

    Objects.nonNull (объект)

    Objects.requireNonNull (объект)

    Objects.equals (объект1, объект2)

  2. начиная с Java 8 вы можете использовать дополнительный класс ( когда использовать )

object.ifPresent(obj -> ...); Java 8

object.ifPresentOrElse(obj -> ..., () -> ...); Java 9

  1. полагаться на контракт метода ( JSR 305 ) и использовать Поиск ошибок . Пометьте свой код аннотациями @javax.annotation.Nullable и @javax.annotation.Nonnnul. Также доступны предварительные условия.

    Preconditions.checkNotNull (объект);

  2. В особых случаях (например, для строк и коллекций) вы можете использовать служебные методы apache-commons (или Google guava):

public static boolean isEmpty (CharSequence cs) // apache CollectionUtils

public static boolean isEmpty (Collection coll) // apache StringUtils

public static boolean isEmpty (Карта map) // apache MapUtils

public static boolean isNullOrEmpty (строка @Nullable String) // Строки гуавы

  1. Когда вам нужно назначить значение по умолчанию, когда null, использовать apache commons lang

открытый статический объект defaultIfNull (объект объекта, объект defaultValue)

7 голосов
/ 28 ноября 2016

Так как Java 7 класс java.util.Objects существует.

Но поскольку Java 8, вы можете использовать методы Objects.isNull(var) и Objects.nonNull(var) класса Objects для проверки нулевого указателя.

Например,

String var1 = null;
Date var2 = null;
Long var3 = null;

if(Objects.isNull(var1) && Objects.isNull(var2) && Objects.isNull(var3))
    System.out.println("All Null");
else if (Objects.nonNull(var1) && Objects.nonNull(var2) && Objects.nonNull(var3))
    System.out.println("All Not Null");
7 голосов
/ 25 января 2016

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

  1. Избегайте отложенная инициализация переменных-членов в максимально возможной степени. Инициализируйте переменные в самом объявлении. Это обработает исключения NullPointerException.

  2. Выберите изменчивость переменных-членов в начале цикла. Эффективно используйте языковые конструкции, такие как final.

  3. Если вы знаете, что дополнения для метода не будут изменены, объявите их как final.

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

    например. Предположим, что один класс в вашем приложении (A.java) поддерживает коллекцию, подобную HashMap. Не предоставляйте public метод получения в A.java и разрешайте B.java напрямую добавлять элемент в Map. Вместо этого предоставьте API в A.java, который добавляет элемент в коллекцию.

    // Avoid
    a.getMap().put(key,value)
    
    //recommended
    
    public void addElement(Object key, Object value){
           // Have null checks for both key and value here : single place
           map.put(key,value);
    }
    
  5. И наконец, эффективно используйте блоки try{} catch{} finally{} в нужных местах.

6 голосов
/ 21 октября 2011

Еще одна альтернатива:

Следующая простая функция помогает скрыть нулевую проверку (я не знаю почему, но я не нашел ее как часть той же обычной библиотеки):

public static <T> boolean isNull(T argument) {
    return (argument == null);
}

Теперь вы можете написать

if (!isNull(someobject)) {
    someobject.doCalc();
}

что является ИМО лучшим способом выражения != null.

5 голосов
/ 06 марта 2014

Я считаю, что предварительные условия для гуавы очень полезны в этом случае. Мне не нравится оставлять нулевые значения исключением нулевого указателя, поскольку единственный способ понять NPE - найти номер строки. Номера строк в рабочей версии и в разрабатываемой версии могут быть разными.

Используя предварительные условия для Guava, я могу проверить нулевые параметры и определить значимое сообщение об исключении в одной строке.

Например,

Preconditions.checkNotNull(paramVal, "Method foo received null paramVal");
5 голосов
/ 07 ноября 2008

Где бы вы ни передавали массив или вектор, инициализируйте их пустыми вместо нуля. - Таким образом, вы можете избежать много проверок на ноль, и все хорошо:)

public class NonNullThing {

   Vector vectorField = new Vector();

   int[] arrayField = new int[0];

   public NonNullThing() {

      // etc

   }

}
5 голосов
/ 12 июля 2018

Вы можете избежать многого, чтобы избежать NullPointerException, просто следуя большинству других ответов на вопрос, я просто хочу добавить несколько больше способов, которые были введены в Java 9 для обработки этот сценарий изящно, а также демонстрирует некоторые из более старых, которые также могут быть использованы, что снижает ваши усилия.

  1. public static boolean isNull(Object obj)

    Возвращает true, если указанная ссылка равна нулю, в противном случае возвращает ложь.

    начиная с Java 1.8

  2. public static boolean nonNull(Object obj)

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

    С Java 1.8

  3. public static <T> T requireNonNullElse​(T obj, T defaultObj)

    Возвращает первый аргумент, если он не равен нулю, а в противном случае возвращает ненулевой второй аргумент.

    С Java 9

  4. public static <T> T requireNonNullElseGet​(T obj, Supplier<? extends T> supplier)

    Возвращает первый аргумент, если он не нулевой, и в противном случае возвращает ненулевое значение supplier.get ().

    С Java 9

  5. public static <T> T requireNonNull​(T obj, Supplier<String> messageSupplier)

    Проверяет, что указанная ссылка на объект не является нулем, и в противном случае выдает настроенное исключение NullPointerException.

    С Java 1.8

Более подробную информацию о вышеупомянутых функциях можно найти здесь .

4 голосов
/ 03 декабря 2012

Вы можете использовать перехватчик перед вызовом метода. Вот на чем аспектно-ориентированное программирование сосредоточено.

Предположим, M1 (тест объекта) - это метод, а M2 - метод, в котором мы применяем аспект перед вызовом метода, M2(Object test2). Если test2 != null, тогда позвоните M1, иначе сделайте другое. Это работает для всех методов, для которых вы хотите применить аспект. Если вы хотите применить аспект для поля экземпляра и конструктора, вы можете использовать AspectJ . Spring также может быть лучшим выбором для аспекта метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...