Я сидел, никого не трогал, изучал андроид 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 переменной останется внутри анонимного класса.
Комментариев нет:
Отправить комментарий