this

this指针指向当前正在调用方法的对象。

  1. this是一个系统隐含的指针被自动附加在非静态的成员函数参数列表中。
  2. 当前时刻,哪个对象调用该函数,那么this就指向当前调用该函数的对象,系统就会自动在该函数的参数列表中添加一个隐藏的this指针,并且把调用该函数的对象地址赋给this指针,这样一来,在函数的内部通过this就可以访问当前正在调用该函数的对象。
    的成员。
    3.静态函数内部,没有this指针。

在一个类里面,有属性和方法,每次以该为模型新建一个对象的时候,系统就会分配一块内存用来存储对象中的变量,但是在以这个类为模板的对象,方法只会分配一次内存,简而言之就是,同一个类new出的多个对象共用这个类里的一个方法。

javascript有指针 javathis指针_构造方法


对象中的变量会被储存在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?
	}
}

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成员。
		
	}
}

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
	}
}

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);
	}
}


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);
	}
}