this
this指针指向当前正在调用方法的对象。
- this是一个系统隐含的指针被自动附加在非静态的成员函数参数列表中。
- 当前时刻,哪个对象调用该函数,那么this就指向当前调用该函数的对象,系统就会自动在该函数的参数列表中添加一个隐藏的this指针,并且把调用该函数的对象地址赋给this指针,这样一来,在函数的内部通过this就可以访问当前正在调用该函数的对象。
的成员。
3.静态函数内部,没有this指针。
在一个类里面,有属性和方法,每次以该为模型新建一个对象的时候,系统就会分配一块内存用来存储对象中的变量,但是在以这个类为模板的对象,方法只会分配一次内存,简而言之就是,同一个类new出的多个对象共用这个类里的一个方法。
对象中的变量会被储存在heap中,而方法被储存在code segment中,每次新建对象的时候,不会再给对象中的方法分配内存空间,那么方法是怎么知道是哪个对象在调用自己呢?
public class Test
{
int i;
int j;
void show()
{
System.out.printf("%d,%d\n",i,j);
}
public static void main(String[] args)
{
Test aa = new Test();//新建了一个aa对象。
//这个对象aa在heap区域分配了两块内存空间,分别存储i和j;
//这个对象的show方法,不在heap中存储而是在名为code segment中的区域存储。
Test bb = new Test();//新建了一个bb对象
//这个对象bb在heap区域分配了两块内存,分别存储i和j;
//这个对象的show方法,不再在code segment里再存储一次。
//因为每个对象中的方法的执行过程都是一样的,定义多了浪费空间
//aa对象与bb对象共用一个show方法
//既然aa与bb共用一个show方法,那系统是怎么知道这个show方法中的i是aa中的i还是bb中的i?
}
}
this是一个系统隐含的指针被自动附加在非静态的成员函数参数列表中。
例子:用C语言中的指针举例
class A
{
public int i;
//*this指针存放A的地址
public void show()//实际写法是public void show(A * this) //用C语言的写法
{ //把传过来的对象的地址赋给this
System.out.printf("%d\n",i);
//这里实际上是System.out.printf("%d\n",(* this).i);//访问A地址中的i属性
}
}
public class Test1
{
public static void main(String args[])
{
A aa1 = new A();
A aa2 = new A();
//新建两个对象
aa1.show();//实际上是 aa1.show(aa1); //现在括号里的aa1实际上是存放A的地址
//把aa1这个值发送给this,this就指向aa1
//哪一个对象调用show方法,(A * this)里保存的就是,调用这个show方法的对象的地址
//比如aa1调用show方法,就把aa1的地址发送给A,然后this取得A的地址也就是aa1的地址。所以aa1调用show方法,this就取得aa1的地址。
//然后*this.i的含义就是,指向调用这个show方法的对象中的i成员。
aa2.show();//实际上是 aa2.show(aa2);
//public void show(A * this) //this代表的是当前正在调用show方法的对象
//无论是aa1调用show方法还是aa2调用show方法,this只指向调用show方法的对象。
//这样show方法就知道,该输出的是哪个对象中的i了。
//注意:内部是这么实现的,但是写代码的时候不能这么写。
//不过show方法中的System.out.printf("%d\n",i);
//可以换成System.out.printf("%d\n",this.i);
//this保存的是调用这个方法的地址,this.i就是调用这个方法的地址中的i成员。
}
}
构造方法中的this与普通方法中的this。
例子:注意对比三个类
class A
{
public int i;
public A(int j)//构造方法
{
i=j;
}
public void show()//普通方法
{
System.out.printf("%d\n",this.i);
//this代表当前正在调用该方法的对象的地址。
//this.i代表当前正在调用该方法的对象的地址中的i成员。
}
}
class B
{
public int a=99;
public B(int a)//形参名与变量名是一样的。
{
a = a;
//这个方法看似是错的,实际是能运行的。
//系统怎么分辨哪个是 int a 哪个是形参a?
}
}
class C
{
public int n=88;
public C(int n)//构造方法
{
this.n=n;//构造方法中的this代表,当前时刻正在创建的对象。
//this.n就是当前时刻正在创建的对象中的n成员。
//当前时刻正在创建的对象是cc。
//cc中的i成员就是值为88的n。
//则另外一个n就是形参n了。
//利用this这样定义形参非常方便。
}
}
public class Test1
{
public static void main(String args[])
{
A aa = new A(2);//
aa.show();//aa.i的值为2
//这个很简单
B bb = new B(2);//把2传给构造方法 (int a)
System.out.printf("%d\n",bb.a);//bb.a的值为99
//bb.a的值为99,说明了 构造方法B里面的a = a 并没有形参a
//而用的是 定义的值为99的int a。 99 = 99。
//但是利用this的功能,就能成功让方法分辨哪个是形参变量哪个是定义的变量
C cc = new C(2);
System.out.printf("%d\n",cc.n);//cc.n的值为2
}
}
this这种用法用来定义构造方法很方便。
class Student
{
int id;
String name;
String sex;
int age;
Student(int id,String name,String sex,int age)
{
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
}
}
public class Test1
{
public static void main(String[] args)
{
Student zhangsan = new Student(0001,"zhangsan","M",18);
System.out.println(zhangsan.id);
System.out.println(zhangsan.name);
System.out.println(zhangsan.sex);
System.out.println(zhangsan.age);
}
}