Положения супер() звонков в Android Eclipse Plugin сгенерировали код надежным?

Во многих методах Android, особенно конструкторах и переопределенных методах, вы должны или даже должны вызывать метод родительского класса с помощью super(). Когда вы используете Eclipse Source > Override/Implement Methods..., вы получаете код из шаблона с тегами TODO следующим образом:

public MyCanvas(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}


@Override
protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub      
    super.onDraw(canvas);
} 

Я не понимаю, что делает суперкласс в каждом случае, поэтому я всегда вставляю свой код в точное местоположение тегов //TODO. В этом примере я бы назвал super() перед моим кодом в конструкторе и после моего кода в onDraw().

Могу ли я всегда полагаться на эти места размещения кода в сгенерированном коде? Есть ли простое правило/объяснение, когда нужно вызвать super()?

Ответ 1

Это хороший вопрос. К сожалению, для этого нет простого правила. Вам нужно знать, что делает реализация суперкласса. Иногда (как в View.onDraw()) реализация суперкласса ничего не делает; вызов super() является безобидным и ненужным. В других случаях (например, Activity.onCreate()) реализация суперкласса выполняет критические операции, которые должны выполняться в какой-то момент обработки подкласса. Иногда то, что происходит, когда вы вызываете super(), должно присутствовать перед любой обработкой в ​​подклассе, иногда в других точках. Иногда вы хотите полностью заменить обработку суперкласса своим собственным, и в этом случае вы вообще не называете super(). У вас есть полная свобода вызывать версию суперкласса в любой точке (или даже в нескольких точках) в вашей логике подкласса.

В конструкторах вызов конструктора суперкласса (если он есть) должен быть первым в этом методе. Если у вас его нет, компилятор автоматически вставляет вызов конструктору без аргументов в суперкласс. (Если у суперкласса нет конструктора без аргументов или если он недоступен для подкласса, компилятор генерирует ошибку.)

Если в документации недостаточно информации, вам нужно посмотреть исходный код. Android-код доступен здесь (Gingerbread release). Код API находится под core.

EDIT Код больше не доступен на git.kernel.org. Вот еще два места, где вы можете просматривать код:

Основной код находится в репозитории Platform > Frameworks > Base

Ответ 2

Могу ли я всегда полагаться на эти места размещения кода в сгенерированном коде?

Нет, иногда вы не хотите называть super.method. Иногда вы хотите называть это первым, иногда на последнем месте и т.д. Это зависит. Но я говорю о методах, никаких конструкторах.

Есть ли простое правило/объяснение, когда нужно вызвать super()?

Вы всегда будете иметь для всех super как предыдущие точки ответа. Единственный случай, когда вы не называете супер, - это когда конструктор суперкласса не имеет параметров; в этом случае компилятор разместит super для вас.

Я не понимаю, что делает суперкласс в каждом случае, поэтому я всегда вставляю свой код в точное место//тегов TODO

Если у вас есть сомнения (я говорю о супер-методах), вы всегда можете взглянуть на исходный код. Поиск Google Code - хороший ресурс для этого. Затем вы можете решить, следует ли поставить код до или после супер-метода; или даже, не ставьте супер-метод вообще.

Имейте в виду, что не применять метод super во время компиляции. Но некоторые методы для android не будут работать, если вы не вызовете супер метод (например, метод onResume класса Activity).

Кроме того, иногда вы решаете, следует ли запускать супер-метод или нет во время выполнения. Рассмотрим этот классический пример:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if( KeyEvent.KEYCODE_BACK == event.getKeyCode() ){
        return true;
    }
    return super.onKeyUp(keyCode, event);
}

Если пользователь нажал клавишу "Назад", вы не будете называть супер-метод. Если пользователь этого не сделал, вы делегируете работу супер-методу.

Ответ 3

Если конструктор явно не вызывает конструктор суперкласса, компилятор Java автоматически вставляет вызов конструктору без аргументов суперкласса. Если супер класс не имеет конструктора без аргументов, вы получите ошибку времени компиляции. У объекта есть такой конструктор, поэтому, если Object является единственным суперклассом, проблем нет.

Проверьте документацию на переопределение неконструктора. Иногда вы хотите назвать супер, иногда нет.