[javase学习笔记]-7.6 this关键字之原理

这一节我们来讲一个关键字,就是this关键字。

我们还是通过例子来看吧:

class Person
{
	private String name;
	private int age;

	Person(String n,int a)
	{
		name = n;
		age = a;
	}

	public void speak()
	{
		System.out.println(name+":"+age);
	}
}
class ThisTest
{
	public static void main(String[] args)
	{
		Person kobe = new Person("KOBE",37);
		kobe.speak();
	}
}

这个例子我们应该很熟悉了,前面几节都在用这个例子,我们再来看一看结果:

很显然,构造函数对对象kobe进行了初始化。

但是我们发现,虽然结果是我们想要的,但是,我们单独看这个构造函数,从可读性的角度我们分析,我们根本就不知道函数传过来的是什么内容,我们可以说一无所知,可阅读性太差了,那么我们再对这个构造函数进行改造:

class Person
{
	private String name;
	private int age;

	Person(String name,int age)
	{
		name = name;
		age = age;
	}

	public void speak()
	{
		System.out.println(name+":"+age);
	}
}

唉,这样不是很清晰了吗,我们一眼就看出这个构造函数要告诉我们初始化对象的姓名和年龄了,我们看结果:

嗯???这是什嘛情况,KOBE人呢?

我们7.4节谈过了构造函数的内存加载过程,但是我们没有提到这里遇到的这种情况,这种情况我们可以说是:成员变量和局部变量重名的问题,此时对于栈内存和堆内存中都会变量name和age,而调用的构造函数会自动到栈内存中寻找这两个变量,而此时,恰好都有,所以系统就会做一个非常有趣的事情,就是把栈内存中的name原赋给本身,而对象的name和age的值其实在堆内存中,所以结果就是我们刚才看到的结果喽。

那么对于这个问题,我们该怎么解决呢?

java给我们解决方案,那就是用一个关键字this来区分成员变量和局部变量。我们再来改造:

class Person
{
	private String name;
	private int age;

	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}

	public void speak()
	{
		System.out.println(name+":"+age);
	}
}

结果:

很好,KOBE同志又回来了。

所以我们可以说,当成员变量与局部变量重名时,我们可以用this来区分。

那么我们就想明白,this到底代表什么呢?java语言说,this代表的是对象。我们还想明白,this代表的是哪个对象?java语言又说,代表的就是当前对象。

专业点的术语是这样定义this的:this就是所在函数所在对象的引用。说简单点就是:this代表本类对象的引用。

我们自己用通俗点的语言来定义:就是哪个对象调用了this所在的哪个函数,this就代表哪个对象,也就是说this就是这个对象的引用。

比如上面的例子中的kobe调用了构造函数Person(String name,int age),那么我们可说this就可以代表kobe这个对象。

那么我们再来对this在内存中的体现过程分析一下,我们继续7.4的过程,只有小的变动。

1.main方法进栈内存,main方法中有一个Person类类型变量kobe;

2.new创建Person对象,在堆内存中创建空间(假如地址为0x0045),该空间中有两个成员变量name和age;

3.对对象的两个成员变量进行初始化,此时会自动选择调用构造函数Person(String n,int a);

4.构造函数Person(String name,int age)进栈内存,参数name="KOBE",age=0也加载入栈。而此时系统会自动为该栈内存中加载一个对象的引用,也就是this,并且把kobe的堆内存地址赋给this;

5.然后在把this.name和this.age的初始化为栈内存中name和age,这样就很清晰了,this.name和this.age我们可以理解为就this所指堆内存中对象的成员变量,此时对象的初始化完成;

6.把地址0x0045赋给main方法中的实例变量kobe;

7.构造函数Person(String name,int age)出栈,释放参数name和age和this引用;

8.执行kobe.speak()语句,调用Person类中的speak()方法,则speak方法进栈,此时系统也会为speak方法加载一个this引用,指向堆内存中的对象地址(0x0045);

9.执行打印语句,跳出speak方法,speak方法出栈,释放this引用;

10.跳出main方法,main方法出栈,程序运行结束。

通过上面的过程分析,我们可以简单的总结出这样一个结论:当在函数中需要用到调用函数的对象时,就用this关键字。

为了更好的理解这个结论,我们把上面的例子可以标准的写成下面这样:

class Person
{
	private String name;
	private int age;

	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}

	public void speak()
	{
		System.out.println(this.name+":"+this.age);
	}
}

我们对这个类方法中的所有成员变量都标准的写成了this.成员变量的格式。

那么我们刚开始看的第一个例子为什么没有this,而结果是也是正确的呢?

很显然,当然对于成员变量与局部变量不重名时,this是可以省略的,但请注意,不是没有,而是省略。

时间: 2024-10-14 17:08:15

[javase学习笔记]-7.6 this关键字之原理的相关文章

[javase学习笔记]-7.12 static关键字的使用场景

这一节我们来看一下在我们开发的过程中,在什么时候我们要用到static关键字进行静态修饰. 我们这里所说的静态,无非就是两种,一种是静态变量,一种是静态函数,我们分这两种情况进行说明static关键字的使用场合. 一.静态变量 我们在7.8节中对static关键字特点和7.9节中成员变量与静态变量区别进行学习的时候就已经很明确的指出了静态变量是共享数据,而对象中封装的特有数据. 因此我们可以这样解释:当分析对象中所具备成员变量的值是相同的,且不需要对象做修改,这时这个成员变量就可以被static

javasE学习笔记:关键字super的使用

/* super 的作用: 1 . super可以在子类中引用父类的成员,通过 .的方式和属性.this相对应. 2. 在子类的构造方法中可以可使用super(参数列表)语句调用父类的构造方法 3. 注意: 子类的构造方法中一定要调用父类的构造方法.... */ javasE学习笔记:关键字super的使用,布布扣,bubuko.com

C++学习笔记7,const关键字的使用(一)。

在C++里面,const关键字的用处很多,使用好const关键字对程序的健壮性大有好处. 首先来看看const一般都用在什么地方. 1.用于定义常量. const用的最多的就是用来定义常量了. const常量有数据类型,而宏常量没有数据类型.编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误. 一个最简单的例子: #include <iostream> using namespace std; int main() { cons

OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 2013-03-23 17:44 16963人阅读 评论(28) 收藏 举报 分类: 机器视觉(34) 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] KAZE系列笔记: OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 OpenCV学习笔记(28)KA

C++学习笔记27,虚函数的工作原理

C++规定了虚函数的行为,但是将实现交给了编译器的作者. 通常,编译器处理虚函数的方法是给每一个对象添加一个隐藏成员.隐藏成员中保存了一个指向函数地址数组的指针. 这个数组称为虚函数表(virtual function table,vtbl).虚函数表中存储了为类对象进行声明的虚函数的地址. 例如:基类对象包含一个指针,该指针指向基类的虚函数表. 派生类对象包含一个指针,该指针指向一个独立的虚函数表.如果派生类提供了虚函数的新定义,虚函数表将保存新的函数地址. 如果派生类没有重新定义虚函数,虚函

php学习笔记day1--基本概念,及原理

作为一个php新手,我一直在寻找着一种快速而有效的学习方法,最后发现,快速掌握知识最快的方法就是输出,把自己学过的知识从新整理,拿出来给大家看,同时也要学会总结归纳,同一些高手交流,才能最快把知识融入自己,从而强化技能,提升能力. 博客园是一个学习的好地方,相同的问题,有不同的解决方案,能够很快的扩大自己的见识和知识体系.能跟更多爱好相同的人在一起讨论问题,是一件很令人开心的事情. 第一天学习笔记. 一.概念了解 1.什么是ip地址 互联网上的每一台电脑或者设备,都有唯一的编号,这个编号不会重复

JavaSE学习笔记(五)——类与对象

一.  类和对象 1.1           面向对象与面向过程的区别 1.面向过程 采用面向过程必须了解整个过程,每个步骤都有因果关系,每个因果关系都构成了一个步骤,多个步骤就构成了一个系统,因为存在因果关系每个步骤很难分离,非常紧密,耦合度高,当任何一步骤出现问题,将会影响到所有的系统.如:采用面向过程生产电脑,那么他不会分CPU.主板和硬盘,它会按照电脑的工作流程一次成型. 2.面向对象 面向对象对会将现实世界分割成不同的单元(对象),实现各个对象,如果完成某个功能,只需要将各个对象协作起

JavaSE学习笔记(一)———Java简介与基础

一.  Java语言简介 1.1           计算机语言的发展过程 计算机语言发展主要分为三个阶段: 1.第一代:机器语言 2.第二代:低级语言 3.第三代:高级语言 1.2           Java发展简史 1.Java 是一种程序开发语言,既然是一门语言,就像其他语言一样,具备一定的语法 和自己的数据结构. 2.Java语言来源于sun公司,sun指的是斯坦福大学网络.由james gosling领导并开发. Java语言的具体发展历程 1991~1995  Sun 为了占领智能

javase学习笔记]-7.7 this之细节与应用

这一节我们接着上一节来继续学习this关键字. 我们之前在7.5节中的构造函数应注意的细节中提到过一个细节就是构造函数可以调用一般函数,但一般函数不能直接调用构造函数.但是我们没有深究构造函数能不能调用构造函数,那么现在我们就来看一看这个问题. 那么构造函数与构造函数之间是怎么访问呢? 为了掌握这个问题,我们必须要明确一个概念,那就是在一个类中的成员如果要被执行,就必须由对象调用.而每个对象都有一个所属的this. java语言给了关键字this这个功能,那就是用this调用构造函数,而且也是通