Не вызывайте overridable-методы в конструкторах

Jul 9, 2013   #жемчужины Android 

Эту штуку я слышал уже много раз, однако только сейчас напрямую с этим столкнулся.

Захотел я унаследовать EditText, чтобы реализовать в нём свои супер-пупер-киллер-фичи.
Перегрузил в нём метод onTextChanged, чтобы показывать иконку-крестик при наличии текста и скрывать её при отсутствии. В нём я обращаюсь к созданному прямо в классе массиву:

private List<String> list = new ArrayList<String>();
@Override
protected void onTextChanged(CharSequence text, ...) {
  ...
  list.add(text.toString()); 
}

(Пример кода, как всегда, высосан из пальца)
В итоге старт активити с этим компонентом получился таким:

java.lang.NullPointerException
at MyFavoriteEditText.onTextChanged(MyFavoriteEditText.java:82)
at android.widget.TextView.setText(TextView.java:3374)
at android.widget.TextView.setText(TextView.java:3226)
at android.widget.EditText.setText(EditText.java:107)
at android.widget.TextView.setText(TextView.java:3201)
at android.widget.TextView.setTransformationMethod(TextView.java:1488)
at android.widget.TextView.applySingleLine(TextView.java:7372)
at android.widget.TextView.(TextView.java:1055)
at android.widget.EditText.(EditText.java:74)

Всё почему? Всё потому, что я попытался прочитать неинициализированное поле класса. А почему оно не инициализировано? А потому что ещё не закончился вызов конструктора суперкласса.
Такая грусть-пичаль.

Поэтому не надо доверять коду ребят из гугла, они тоже создают потенциальные проблемы, которые мне приходится обходить лишними if(... != null) {...} в местах, где, казалось бы, null быть не должен.

comments powered by Disqus