[javase学习笔记]-7.6 thiskeyword的原理
这一节我们来讲一个keyword。就是thiskeyword。
我们还是通过样例来看吧:
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给我们解决方式。那就是用一个keywordthis来区分成员变量和局部变量。我们再来改造:
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方法出栈,程序执行结束。
通过上面的过程分析,我们能够简单的总结出这样一个结论:当在函数中须要用到调用函数的对象时。就用thiskeyword。
为了更好的理解这个结论,我们把上面的样例能够标准的写成以下这样:
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是能够省略的,但请注意,不是没有,而是省略。
[javase学习笔记]-7.6 thiskeyword的原理的更多相关文章
- [javase学习笔记]-7.7 thiskeyword的细节与应用
这一节我们接着上一节来继续学习thiskeyword. 我们之前在7.5节中的构造函数应注意的细节中提到过一个细节就是构造函数能够调用一般函数,但一般函数不能直接调用构造函数.可是我们没有深究构造函数 ...
- javaSE学习笔记(17)---锁
javaSE学习笔记(17)---锁 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率.本文旨在对锁相关源码(本文中的源码来自JDK 8).使用场景进行举例,为读 ...
- JavaSE学习笔记(14)---File类和IO流(字节流和字符流)
JavaSE学习笔记(14)---File类和IO流(字节流和字符流) File类 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 构造方 ...
- JavaSE学习笔记(13)---线程池、Lambda表达式
JavaSE学习笔记(13)---线程池.Lambda表达式 1.等待唤醒机制 线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同. 比如:线程A用来生成包子的,线程B用 ...
- javaSE学习笔记(10)---List、Set
javaSE学习笔记(10)---List.Set 1.数据存储的数据结构 常见的数据结构 数据存储的常用结构有:栈.队列.数组.链表和红黑树. 1.栈 栈:stack,又称堆栈,它是运算受限的线性表 ...
- JavaSE学习笔记(9)---集合类和泛型
JavaSE学习笔记(9)---集合类和泛型 1.Collection集合 集合概述 在前面我们已经学习过并使用过集合ArrayList<E> ,那么集合到底是什么呢? 集合:集合是jav ...
- ZooKeeper学习笔记(二)——内部原理
zookeeper学习笔记(二)--内部原理 1. zookeeper的节点的类型 总的来说可以分为持久型和短暂型,主要区别如下: 持久:客户端与服务器端断开连接的以后,创建的节点不会被删除: 持久化 ...
- javaSE学习笔记(16)---网络编程
javaSE学习笔记(16)---网络编程 基本概念 如今,计算机已经成为人们学习.工作.生活必不可少的工具.我们利用计算机可以和亲朋好友网上聊天,也可以玩网游.发邮件等等,这些功能实现都离不开计算机 ...
- javaSE学习笔记(15) ---缓冲流、转换流、序列化流
javaSE学习笔记(15) ---缓冲流.转换流.序列化流 缓冲流 昨天复习了基本的一些流,作为IO流的入门,今天我们要见识一些更强大的流.比如能够高效读写的缓冲流,能够转换编码的转换流,能够持久化 ...
随机推荐
- 小学生绞尽脑汁也学不会的python(异常,约束,MD5加密,日志处理)
小学生绞尽脑汁也学不会的python(异常,约束,MD5加密,日志处理) 异常处理(处理) 1.产生异常.raise 异常类(),抛出异常2. 处理异常: try: xxxxx # 尝试执行的代码. ...
- Java基础学习总结(47)——JAVA输入输出流再回忆
一.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列. Java的I/O流提供了 ...
- java源码之TreeSet
1,TreeSet介绍 1)TreeSet 是一个有序的集合,它的作用是提供有序的Set集合.2)TreeSet 继承于AbstractSet,所以它是一个Set集合,具有Set的属性和方法.3)Tr ...
- dubbo标签
<dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心. <dubbo:reference/&g ...
- 【c++版数据结构】之顺序表的实现
SeqList.h #ifndef SEQLIST_H #define SEQLIST_H #include<iostream> using namespace std; typedef ...
- Linux防火墙限制指定port仅仅能由指定IP訪问
须要对redis的端口做限制,仅仅能让公司内指定IP的机器訪问 -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A ...
- 30个php操作redis经常用法代码样例
这篇文章主要介绍了30个php操作redis经常用法代码样例,本文事实上不止30个方法,能够操作string类型.list类型和set类型的数据,须要的朋友能够參考下 redis的操作非常多的,曾经看 ...
- m_Orchestrate learning system---十六、如何快速在一堆字符图标中找到所需
m_Orchestrate learning system---十六.如何快速在一堆字符图标中找到所需 一.总结 一句话总结:find查找字符 比如说找teacher feedback 的图标,可以多 ...
- hdoj--1010--Tempter of the Bone(搜索+奇偶剪枝)
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- 4.git "Could not read from remote repository.Please make sure you have the correct access rights."解决方案
转自:https://zhiku8.com/git-could-not-read-from-remote-repository.html 我们在使用git clone 或其他命令的时候,有时候会遇到这 ...