Страницы

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

вторник, 5 февраля 2019 г.

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

Я сидел, никого не трогал, изучал андроид 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 берет значение этой константы, ведь метод, в локальном контексте которого она существовала завершился и ее больше быть не должно.
Неужели при такой перегрузке метода он запомнит ссылку на эту константу и она продолжит существовать? Объясните пожалуйста как это работает!


Ответ

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

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

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