面向对象传值和关键字this的秘密

来源:互联网 发布:iis7怎么执行php 编辑:程序博客网 时间:2024/04/24 23:22

我相信对于很多人来说,对面向对象这块都不是很懂,或者是半知半解,有很多甚至上班大半年到一年的都跑回来从新看面向对象的内容,因为这一块实在是太重要对于我们java语言做开发的人,可以说面向对象,数据库,和网络编程是程序员的三剑客,而传值和this关键字这块无疑是面向对象很重要的一部分,我现在学到安卓了,但是今天做一个小项目的时候突然觉得我对面向对象传值那块又不懂了,以下是我的问题:

先看一个小程序,还没有学习到数据库的朋友可以跳过,并不影响你继续阅读来了解java传值this,和初始化这方面的问题

class Person(){
  private  int age ;
  private  String name;


public void setAge(String age)
{
this.age = age;
 
}
public String getAge()
{
return age;
}


public void setName(String name)
{
this.name = name;
 
}
public String getName()
{
return name;
}
//构造函数
public Person(int age,String name){
this.age = age;
this.name = name;
}
public String toString()
{
return age+ ","+name;

}
}








public class MainActivity extends Activity
{


ArrayList<Person> personList = null;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


     layout = (LinearLayout) findViewById(R.id.line);
personList = new ArrayList<Person>();
//数据库读取数据
MySQLiteOpenHelper oh = new MySQLiteOpenHelper(this);
SQLiteDatabase dbDatabase = oh.getWritableDatabase();
Cursor cursor = dbDatabase.query("person", null, null, null, null,
null, null, null);


while (cursor.moveToNext())
{
     // 查询出来
     String age = cursor.getString(cursor.getColumnIndex("age"));
     String name = cursor.getString(cursor.getColumnIndex("name"));

//把读取到的值给下面Person参数
     Person p = new Person(age, name);
personList.add(p);
对,这是个很简单的程序,但是这里面涉及到java的传值与对this,和堆的理解,如果读者还没有涉及到数据库这块,数据库那块可以忽略,就从Person p = new Person(age, name);这里开始看起,开始我做这个的时候迷迷糊糊的做完了,后来我突然感觉不对劲啊,就 Person p = new Person(age, name);这行来说,我不是已经从数据库里面已经得到了age和name吗?怎么我还要返回给Person类setName方法下的哪行代码this.name = name呢?
苦思不得解,其实呢?这里面涉及到java最基础的东西栈和堆的问题,说到这里,我们就要解析下这行代码:
Person p = new Person(age, name);
有人说,这行代码不就是new一个对象吗?是的,现在我们就通过这行代码来理解栈和堆吧:
1:当我们new一个对象的时候,java虚拟机将Person.class文件加载至内存
2:会在内存开辟空间
其中Person p是他栈内存中的,而new Person()和成员变量private  int age是在堆内存的
具体看下面的图


还有一个问题我们要知道this.name=name,这句话,其实这句话的含义很简单,就是上面我们new Person(age, name)给了setName这个函数的参数,而这个参数是局部变量,我们都知道局部变量和成员变量不同,局部变量的保存在栈内存的,而这个参数给了this.name,那么大家一定会想,那这样说this.name不就是成员变量里面的name吗?其实不是的,详情请继续往下阅读:
我们都知道this一般代表的是当前对象,而每一个对象创建的时候在栈内存里面都有一个this,到这里肯定有些人不明白了
this.name=name;
栈内存给栈内存?对,可以这样说,因为this代表的是当前对象的引用,我可以
Person p = new Person(age, name);
也可以是
Person s = new Person(age, name);
反正就是说我可以new无数个对象,而运行哪一个对象,this他代表的就是当前的对象,我们以对象p为例
我们知道p获得了堆内存的地址,他的引用就指向了堆内存,也就是可以访问堆内存的成员,那么this就是p,也就是说this他指向的也是堆内存当前的对象
我们可以这样想
Person s = new Person(20, "zhangsan");
Person p = new Person(40, "lisi");
如果我们当前运行的是p对象
那么this.name = name是不是获得了这个值,这个两个都是在栈内存里面,而this.name指向的是当前p对象在堆内存的引用,所以在堆内存的那个name 和age就被覆盖掉了
到这里,我总结两句话就是,1:对象p只能从堆内存中获取数据:2:就是private  String name成员变量他至始至终都没有改变,都是null和0
而上面我疑惑的那个问题也解决了,就是我们不能在栈内存里面取值,只能在堆内存里面取值,这也是为什么一定要把值给setName的原因了

最后共勉以下学习的朋友:王国维对于人生境界的三句话:

昨夜西风调碧树,独上高楼:  对人生的迷惑和孤独和不知前路几何应该是我们年轻人都有的吧?

衣带渐宽终不悔,为伊消得人憔悴:既然我们选择了程序员这个职业,就必须要耐住寂寞,不要后悔

众里寻他千百度,蓦然回首,那人却在灯火阑珊处 :经过时间和程序量的积累,不知不觉你就是大神了,哈哈




0 0