java基础知识-传值和传引用
背景:在做项目时,一直很纳闷Activity的list通过MyAdapter构造方法传给Adapter类的mContext了,为什么对于list的修改,只需要调用adapter.notifyDataSetInvalidated();或者adapter.notifyDataSetChanged();就可以更新列表显示。
在如下这个小实例中在MyListActivity类中定义一个list,如下:
private List<String> list = new ArrayList<String>();
在MyAdapter构造时调用构造方法,作为参数传入,如下:
adapter = new MyAdapter(MyListActivity.this, list);
然后看一下MyAdapter构造方法,如下,注意一下:在构造方法中将传入的content直接赋值给MyAdapter类的成员变量mContext。
public MyAdapter(Context context, List<String> content) {
inflater = LayoutInflater.from(context);
this.mContent = content;
}
如果将以上构造方法修改为这样,在点击添加按钮时,列表不会更新显示添加项:
public MyAdapter(Context context, List<String> content){
mContent = new ArrayList<String>();
mContent.clear();
mContent.addAll(content);
}
部分代码如下:
public class MyListActivity extends Activity {
private List<String> list = new ArrayList<String>();
private ListView lv;
private Button btn_add;
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_listitem_addclicklistener);
lv = (ListView) findViewById(R.id.lv);
adapter = new MyAdapter(MyListActivity.this, list);
lv.setAdapter(adapter);
btn_add = (Button)findViewById(R.id.btn_add);
btn_add.setOnClickListener(listener);
initData();
}
/**
* 初始化list中数据
*/
private void initData(){
list.add("aabbcc");
list.add("ddeeff");
}
private OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View v) {
addToList();
adapter.notifyDataSetInvalidated();
}
};
/**
* 初始化显示内容
*/
private void addToList() {
list.add("happy");
list.add("beautiful");
list.add("run");
}
class MyAdapter extends BaseAdapter {
private LayoutInflater inflater;
private List<String> mContent;
public MyAdapter(Context context, List<String> content) {
inflater = LayoutInflater.from(context);
this.mContent = content;
}
@Override
public int getCount() {
return mContent.size();
}
@Override
public Object getItem(int position) {
return mContent.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.clickitem, null);
holder = new ViewHolder();
holder.tv = (TextView) convertView.findViewById(R.id.tv01);
holder.ib = (ImageButton) convertView.findViewById(R.id.ib01);
holder.ib_delete = (ImageButton)convertView.findViewById(R.id.ib_delete);
holder.tv = (TextView) convertView.findViewById(R.id.tv01);
holder.ib = (ImageButton) convertView.findViewById(R.id.ib01);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tv.setText(mContent.get(position));
return convertView;
}
class ViewHolder {
TextView tv;
ImageButton ib;
ImageButton ib_delete;
}
}
}
问题分析:涉及java的值传递还是引用传递。说明List是引用传递的。
概念:
值传递:指的是在方法调用时,传递的是值的拷贝。
引用传递:指的是在方法调用时,传递的引用的地址,也就是变量所指向的内存空间的地址。
在网上搜索了一下,有人总结了要点:
1.对象类型(Object,数组,容器……)传引用。
2.基本数据类型(int char long double float…)就是传值
3.String,Integer, Double等immutable类型因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待。可以认为是传值。
Integer 和 String 一样。保存value的类变量是Final属性,无法被修改,只能被重新赋值/生成新的对象。 当Integer 做为方法参数传递进方法内时,对其的赋值都会导致 原Integer 的引用被指向了方法内的栈地址,失去了对原类变量地址的指向。对赋值后的Integer对象做得任何操作,都不会影响原来对象。
参考 http://blog.youkuaiyun.com/yangliuy/article/details/43230681
参考 http://www.zhihu.com/question/31203609