Java this关键字 学习笔记
前言:
这篇博文就是系统的学习一下Java中的this关键字,本人对this关键字的理解知识简单的停留在对 类的成员变量进行赋值,这次所以决定系统的体会一下this 关键字
转自:https://blog.csdn.net/ccpat/article/details/44515335
一、构造方法中的this关键字
构造方法是一个类的对象在通过new关键字创建时自动调用的,在程序中不能向调用其他方法一样通过方法名(也就是类名)来调用。但如果一个类有多个构造方法,可以在一个构造方法中通过this(paras…)来调用其他的构造方法。
使用this来调用其他构造方法有如下几个约束。
1) 只能在构造方法中通过this来调用其他构造方法,普通方法中不能使用。
2) 不能通过this递归调用构造方法,即不能在一个构造方法中通过this直接或间接调用该构造方法本身 。
class test {
test() {
this(1);
}
test(int a){
this();
}
test(int a, int b) {
this(1, 2);
}
}
解释:test()方法中调用了 test(int)构造方法,而test(int)构造方法又调用了test()构造方法,构成递归调用。test(int, int)中调用了自身,也构成了递归调用。都是不允许的。
3) 通过this调用其他构造方法必须放在构造方法的第一行中执行。
由于super调用父类的构造函数也必须放在构造方法的第一行中执行,因此,通过this和super调用构造方法不能同时出现一个构造方法中。也不能在一个构造方法中多次调用不同的构造方法。
在构造方法中也可以使用this关键字来访问本类中的成员变量和成员函数。其用法和非构造方法中的this关键字相同。
二、非构造方法中的this关键字
在Java中可以通过通过this关键字来调用类中的成员变量和方法。其用法是。
1) this.xxx; 访问类中的成员变量xxx
2) this.yyy(paras…); 访问类中的成员方法yyy
3) this; 当前类对象的引用
this关键字访问类的成员变量和成员函数时不受访问权限的控制,可以访问本类中所有的成员变量和方法,包括private的成员变量和方法。也可以通过this访问本类的static成员,不过由于static成员可以通过类名直接访问,如果通过this来访问会有“The static field ××× should be accessed in a static way”的警告信息。不能在类的static成员或static块中使用this。
三、继承关系下的this关键字
在继承关系下,父类中的this关键字并不总是表示父类中的变量和方法。this关键字的四种用法如前文所述,列举如下。
1) this(paras…); 访问其他的构造方法
2) this.xxx; 访问类中的成员变量xxx
3) this.yyy(paras…); 访问类中的成员方法yyy
4) this; 当前类对象的引用
对第一种,无论子类是否有相同参数的构造方法,this(paras…);访问的始终是父类中的构造方法。
对第二种,无论子类是否有覆盖了该成员变量,this.xxx;访问的始终是父类中的成员变量。
对第三种,如果子类重写了该成员方法,则this.yyy(paras…);访问的是子类的成员方法,如果子类没有重写该成员方法,则this.yyy(paras…);访问的是父类的成员方法。
对第四种,this始终代表的是子类的对象。
public class ClassTest {
public static void main(String[] args) {
Child child = new Child();
child.show();
}
}
class Parent {
public String str;
Parent(){
this(1);
}
Parent(int a) {
this.str = "Parent";
this.show();
}
public void show() {
System.out.println(this.str);
}
}
class Child extends Parent {
public String str;
Child() {
}
Child(int a) {
str = "Child";
}
public void show() {
System.out.println(str);
super.show();
}
}
main()函数中有两条语句,new Child()和child.show()。
第一条语句new Child()时要执行Child类的构造方法,但是Child类是Parent类的子类,因此会先执行Parent类的构造方法。
Child类的无参构造函数中没有使用super和this来调用父类或本类中的其他的构造方法,因此会调用父类的无参构造函数。
在父类的无参构造函数Parent()中调用了执行了this(1),此调用表示执行父类中有一个整数参数的构造方法,虽然子类中也有一个有一个整数参数的构造方法,但是并不会被执行。
父类中有一个整数参数的构造方法执行this.str=”Parent”,这里的this.str代表的是父类中的成员变量str,虽然子类中也有一个成员变量str,但是并不会被赋值。
将父类中的成员变量str赋值为”Parent”后,接着执行了this.show(),虽然父类中有一个show()方法,但由于子类重写了show()方法,所以this.show()执行的子类的show()方法。
子类的show()方法首先执行了打印str的操作,此时打印的显然是子类中的str,子类的str没有被赋值,因为打印null。
接着子类的show()方法执行了super.show(),即调用了父类的show()方法,在父类的show()方法中执行了打印this.str的操作,this.str同样代表父类中的成员变量str,因此打印”Parent”。
第二条语句child.show()先是执行子类的show()方法,子类的show()先是打印了子类的str值(null),然后执行了父类的show()打印了父类的str值(”Parent”)。
两条语句的打印结果为null, Parent, null, Parent。
如果将第一条语句改为new Child(1),则执行的是子类的有一个整数参数的构造方法,仍然是先执行父类的无参构造方法,初始化父类的str为”Parent”,然后执行子类的show(),子类的show()打印子类的str值(null),然后执行父类的show(),父类show()打印父类的str值(”Parent”),然后执行子类的构造方法将子类的str初始化为”Child”。
第二条语句child.show()先是执行子类的show()方法,子类的show()先是打印了子类的str值(”Child”),然后执行了父类的show()打印了父类的str值(”Parent”)。
两条语句的打印结果为null, Parent, Child, Parent。
四、super和this的异同
super在一个类中用来引用其父类的成员,它是在子类中访问父类成员的一个桥梁,并不是任何一个对象的引用,而this则表示当前类对象的引用。在代码中Object o = super;是错误的,Object o = this;则是允许的。
super关键字的作用在于当子类中覆盖了父类的某个成员变量,或者重写了父类的某个成员方法时还能够访问到父类的成员变量和成员方法。如果子类中没有重写父类的成员变量和成员方法,则子类会继承父类的所有非private的成员变量和成员方法。这时在子类中无论通过this来访问成员和通过super来访问成员,结果都是一样的。
五、super.getClass()和this.getClass()
getClass()是Object类定义的一个final方法,所有Java类的getClass()都继承自Object类。如前文所述,如果子类没有重写父类的某个成员方法,那么通过super来访问还是还是通过this来访问结果都是一样的。因此,super.getClass()和this.getClass()结果是一样的。Object类的getClass()方法返回的是该对象的运行时类,一个对象的运行时类是该对象通过new创建时指定的类。因此,super.getClass()和this.getClass()返回的都是new对象时指定的类。
public class ClassConstructorTest {
public static void main(String[] args) {
Child child = new Child();
child.show();
}
}
class Parent {
private Parent mSelf;
Parent(){
mSelf = this;
}
public void show() {
System.out.println(this.getClass().getName());
System.out.println(super.getClass().getName());
System.out.println(mSelf.getClass().getName());
}
}
class Child extends Parent {
public void show() {
System.out.println(this.getClass().getName());
System.out.println(super.getClass().getName());
super.show();
}
}
打印的类名都是Child。
Java this关键字 学习笔记的更多相关文章
- java之jvm学习笔记十三(jvm基本结构)
java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...
- 20155327 java第四周学习笔记
20155327 java第四周学习笔记 五六章知识整理 1子类与父类 父类是接口或者是抽象类,子类必须继承自父类. 2子类的继承性 在Java中,通过关键字extends继承一个已有的类,被继承的类 ...
- 《深入理解Java虚拟机》学习笔记
<深入理解Java虚拟机>学习笔记 一.走近Java JDK(Java Development Kit):包含Java程序设计语言,Java虚拟机,JavaAPI,是用于支持 Java 程 ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- Java多线程技术学习笔记(二)
目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...
- Java安全防御学习笔记V1.0
Java安全防御学习笔记V1.0http://www.docin.com/p-766808938.html
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- java之jvm学习笔记三(Class文件检验器)
java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...
- java之jvm学习笔记五(实践写自己的类装载器)
java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...
随机推荐
- ArcGIS AddIN Sample学习笔记
1.AddInEditorExtension 功能描述:编辑器扩展,实现在编辑要素,对编辑事件的监听,及对新创建的要素的处理 核心代码: void Events_OnStartEditing() { ...
- word-break和word-wrap的使用和区别
问题起源: 中文是一个字就是一个单词,而英文字母要有一个空格才将他们分割为一个单词:文字换行没事,主要是英文 <!DOCTYPE html> <html> <head&g ...
- 细说一下position(定位),以及其他的小知识
细说:position 位置 1.只要使用定位,必须要有一个相对的参照物.relative 2.具体定位的那个1元素需要加position:absolute:绝对的 绝对的:就是具体到某一个 ...
- openERP笔记,自定义开发模块
##目标 OpenERP模块基本结构 使用模块添加额外的字段(Date Required和Rush Order) 扩展视图, 让OpenERP能够显示新的字段 修改用于OpenERP工作流的可用状态 ...
- vs自定义类模板
.找到VS安装目录,我的目录是:C:Program Files (x86)Microsoft Visual Studio 12.0 .在C:Program Files (x86)Microsoft V ...
- Jedis简介
实际开发中,我们需要用Redis的连接工具连接Redis然后操作Redis, 对于主流语言,Redis都提供了对应的客户端: https://redis.io/clients https://redi ...
- js 整数型数组和字符型数组相互转换
需求背景: 需要将 a = [1,2,3,4,5] 转换成 a = ['1','2','3','4','5'](整数型数组转换成字符型没找到直接的方法,思路就是先将数组转换成字符串,然后再将字符串转 ...
- 家庭记账本之微信小程序(四)
json的学习 JSON:JavaScript 对象表示法(JavaScript Object Notation). JSON 是存储和交换文本信息的语法.类似 XML. JSON 比 XML 更小. ...
- Spring 部分常用注解
最近在Spring-MVC的项目,把一些自己在项目中使用到的注解整理一下. 1.@Controller 对应表现层的Bean,也就是Struts中对应的Action: 使用这个注解之后,就是把当前Be ...
- Jumpserver(跳板机、堡垒机)启动jms Django连接mysql数据库报错
解决办法 根据报错信息 , 去查看官方手册 在settings.py文件夹加入DATABASES['OPTIONS']['init_command'] = "SET sql_mode='ST ...