Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

Откуда onClick берет значение константы, ведь метод, в локальном контексте которого она существовала завершился и ее больше быть не должно?

#java #android #jvm


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

public void onBindViewHolder(ViewHolder holder, final int position) {
    CardView cardView = holder.cardView;
    ImageView imageView = (ImageView) cardView.findViewById(R.id.image_info);
    Drawable drawable = ContextCompat.getDrawable(cardView.getContext(), imgResIds[position]);
    imageView.setImageDrawable(drawable);
    ((TextView) cardView.findViewById(R.id.text_info)).setText(captions[position]);
    if(listener != null){
        cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listener.onClickListener(position);
            }
        });
    }
}


То, что никак не укладывается в моей голове - это константа position, в моем понимании
эта констант существует как локальная переменная метода

onBindViewHolder


следовательно на момент создания объекта типа View.OnClickListener она определена
и существует, но вызов onBindViewHolder завершится раньше, чем будет вызван метод onClick
ранее созданного объекта типа View.OnClickListener и я не понимаю откуда onClick берет
значение этой константы, ведь метод, в локальном контексте которого она существовала
завершился и ее больше быть не должно.

Неужели при такой перегрузке метода он запомнит ссылку на эту константу и она продолжит
существовать? Объясните пожалуйста как это работает!
    


Ответы

Ответ 1



Локальные переменные создаются на стеке и уничтожаются при выходе из метода. final переменные изначально тоже на стеке. Но для анонимного класса View.OnClickListener эта final переменная будет скопирована в хип и будет создано синтетическое поле внутри анонимного класса. Так что, даже когда метод завершится, очистится только локальный стек, копия final переменной останется внутри анонимного класса.

Комментариев нет:

Отправить комментарий