Идея состоит в том, чтобы потерпеть неудачу быстро. Например, рассмотрим этот глупый класс:
public class Foo {
private final String s;
public Foo(String s) {
this.s = s;
}
public int getStringLength() {
return s.length();
}
}
Допустим, вы не хотите разрешать нулевые значения для s
. (иначе getStringLength
выкинет NPE). С классом как есть, к тому времени, когда вы поймаете этот null
, будет слишком поздно — очень трудно выяснить, кто его туда положил. Виновником вполне может быть совершенно другой класс, и этот экземпляр Foo
мог быть сконструирован давным-давно. Теперь вам нужно прочесать свою кодовую базу, чтобы выяснить, кто мог поместить туда значение null
.
Вместо этого представьте себе этот конструктор:
public Foo(String s) {
this.s = checkNotNull(s);
}
Теперь, если кто-то вставит туда null
, вы узнаете сразу же — и у вас будет трассировка стека, точно указывающая на вызов, который пошёл не так.
В другой раз это может быть полезно, если вы хотите проверить аргументы, прежде чем предпринимать действия, которые могут изменить состояние. Например, рассмотрим этот класс, который вычисляет среднее значение всех длин строк, которые он получает:
public class StringLengthAverager {
private int stringsSeen;
private int totalLengthSeen;
public void accept(String s) {
stringsSeen++;
totalLengthSeen += s.length();
}
public double getAverageLength() {
return ((double)totalLengthSeen) / stringsSeen;
}
}
Вызов accept(null)
вызовет выброс NPE, но не раньше, чем stringsSeen
будет увеличено. Это может быть не то, что вы хотите; как пользователь класса, я могу ожидать, что если он не принимает нули, то его состояние должно быть неизменным, если вы передадите нулевое значение (другими словами: вызов должен завершиться ошибкой, но он не должен сделать объект недействительным). Очевидно, в этом примере вы также можете исправить это, получив s.length()
перед увеличением stringsSeen
, но вы можете видеть, что для более длинного и сложного метода может быть полезно сначала проверить, что все ваши аргументы действительны, и только затем изменить состояние :
public void accept(String s) {
checkNotNull(s); // that is, s != null is a precondition of the method
stringsSeen++;
totalLengthSeen += s.length();
}
person
yshavit
schedule
03.10.2014
checkNotNull(reference, errorMessageTemplate, errorMessageArgs)
: guava.dev/releases/23.0/api/docs/com/google/common/base/ - person Vadzim   schedule 16.06.2020