2014-01-12 1 views
0

Ниже приведен код для ленивой инициализации члена экземпляра. Это оставляет мне вопрос о том, когда выполнять проверку параметров. В коде есть две разные функции, выполняющие проверку NPE, один задерживает ее, а другой нет. Я выбрал первый вариант, но просто любопытно узнать, что такое отраслевая конвенция/лучшая практика.Должна ли выполняться проверка param lazily

public class FreeMain { 

    private List<Integer> fooList; 

    FreeMain () { } 

    /** 
    * This code does a check null pointer kind of just in time. 
    * 
    * @param barList 
    */ 
    public void putListExceptionCheckDoneLater(List<Integer> barList) { 
     if (this.fooList == null) { 
      if (barList == null) throw new NullPointerException(); 
      this.fooList = barList; 
     } 
    } 

    /** 
    * In the even that fooList != null, 
    * throwing an exception would be of no benefit, 
    * since regardless of input, null or not, net effect would still be a no-op. 
    * 
    * @param args 
    */ 
    public void putListExceptionCheckDoneBefore(List<Integer> barList) { 
     if (barList == null) throw new NullPointerException(); 
     if (this.fooList == null) { 
      this.fooList = barList; 
     } 
    } 

    public static void main(String[] args) { 

    } 
} 

Этого код специально разработан, чтобы задать конкретное сомнение, поэтому, пожалуйста, воздержитесь от вопросов как why not use constructor to pass list ? и т.д., или предложить улучшения кода, которые не связаны с этим вопросом.

+0

Я бы сказал, выполнить проверку параметров первой. Итак, я бы пошел с 'putListExceptionCheckDoneBefore'. Плюс, я думаю, что это более эффективно (* сэкономить чек *). – mre

ответ

3

Я не вижу смысла откладывать проверку параметров, конечно, для чего-то такого же легкого, как проверка на null. И это имеет определенные недостатки:

  • (True) ленивая проверка делает ваш код более сложным.

  • (True) ленивая проверка приведет к ошибкам проверки, появляющимся, когда уже слишком поздно что-то делать с ними.


Сказав, что логика вашего примера не имеет особого смысла для меня. Реальная разница между двумя версиями заключается в том, что первый не проверяет свой аргумент вообще, если он не собирается его использовать. Это НЕ то, что означает «ленивый». Это просто делает вещи в другом порядке ... и дает разные результаты в результате.

(Для чего это стоит, я бы предпочел, чтобы проверить, что barList не null все время ... при условии, что она никогда не смысл для параметра быть null. Таким образом, скорее всего, . забрать ошибки ранее)


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

public class LazyValidationExample { 

    private List<Integer> fooList; 

    public void putListExceptionCheckDoneLater(List<Integer> barList) { 
     this.fooList = barList; 
    } 

    public List<Integer> getList() { 
     if (this.fooList == null) throw new NullPointerException(); 
     return this.fooList; 
    } 
    ... 
}