为什么我需要在baseAdapter的getView里面做obj final?

时间:2014-02-03 15:42:34

标签: android baseadapter

我正在尝试扩展baseAdapter。并在onClick事件中获取对象。但它的说法是,obj需要被宣布为最终版。 有人告诉我obj(aStudent)无法在点击事件中找到?如果有,为什么?

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) adapterContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View rowView = inflater.inflate(R.layout.custome_adapter_list_row_item, parent, false);

    TextView lblStudentName = (TextView) rowView.findViewById(R.id.lblStudentName);
    TextView lblStudentAge = (TextView) rowView.findViewById(R.id.lblStudentAge);
    Button btnNext = (Button) rowView.findViewById(R.id.lbllist);

    **final  Student aStudent = studentDataHolder.get(position);**

    if (aStudent != null) {
        lblStudentName.setText(aStudent.getName());
        lblStudentAge.setText("Age : " + aStudent.getAge());

        btnNext.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                Toast.makeText(adapterContext, "Position is"+aStudent.getName(), Toast.LENGTH_LONG).show();
            }
        });



    }
    return rowView;

}

就我所知,代码每次从数组中取一行时都会创建一个Student的新对象。我错了吗?但是,为什么还要最终?

2 个答案:

答案 0 :(得分:2)

这需要一些时间让我理解,但这是我的推理。当您将变量声明为final时,您正在“告诉”编译器(除其他事项外)即使在本地作用域消失之后该变量也应该可用,并且一旦实例化它就不能重新分配。为了澄清,您将侦听器声明为内部类。按下Button时将触发侦听器。在Button完成执行后很久就会按下getView(),并将其从堆栈中删除。这将导致问题,因为aStudent将不再存在于内存中。通过声明final,即使从堆栈中删除方法,aStudent也会保留。

答案 1 :(得分:1)

你需要让它成为最终的,因为你在一个匿名的内部类中使用它。

以下链接提供了更好的解释

Why Java inner classes require "final" outer instance variables?

引用

  

匿名类无法访问其封闭的局部变量   未被宣布为最终或有效最终的范围。

http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html#accessing