前言:

  这篇博文就是系统的学习一下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关键字 学习笔记的更多相关文章

  1. java之jvm学习笔记十三(jvm基本结构)

    java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...

  2. 20155327 java第四周学习笔记

    20155327 java第四周学习笔记 五六章知识整理 1子类与父类 父类是接口或者是抽象类,子类必须继承自父类. 2子类的继承性 在Java中,通过关键字extends继承一个已有的类,被继承的类 ...

  3. 《深入理解Java虚拟机》学习笔记

    <深入理解Java虚拟机>学习笔记 一.走近Java JDK(Java Development Kit):包含Java程序设计语言,Java虚拟机,JavaAPI,是用于支持 Java 程 ...

  4. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  5. Java多线程技术学习笔记(二)

    目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...

  6. Java安全防御学习笔记V1.0

    Java安全防御学习笔记V1.0http://www.docin.com/p-766808938.html

  7. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  8. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  9. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

随机推荐

  1. 4.express 框架

    express express 官网:http://expressjs.com/ 中文:http://www.expressjs.com.cn/ 库:jquery 一堆 的属性和方法 框架:expre ...

  2. 使用 jQuery 调用 ASP.NET AJAX Page Method

    文章来源:http://chungle.iteye.com/blog/406054 说到轻量级的客户端通信,我注意到大多数人喜欢使用 ASP.NET AJAX Page Method 多于 ASMX ...

  3. PAT甲级1141 Ranking of Institutions

    题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805344222429184 题意: 给定几个学生的PAT分数和学校 ...

  4. F#周报2019年第4期

    新闻 F# 4.6预览 fuget.org现在显示包依赖从属,你曾经想要了解谁在使用你的类库吗?现在你可以知道了! F#被加入Wikipedia的流式接口页面 采访Erik Schierboom Az ...

  5. java_工厂模式

    定义: 初学者总是把所有的代码写在一个类里面,这样是非常危险的,因为所有错误集中在一个类里了,而且代码一长,调试就很困难 所以参照工厂流水线,分车间分模块来写代码,在实际操作中也就是说将代码模块化,封 ...

  6. 单片机小白应该如何学习stm32的一些实践心得!

    嵌入式搬砖道路上的大三狗一枚,撑死算个初学者吧.才学有限,下面仅仅是本人对STM32学习的一点心得与建议,希望对题主有帮助吧. 心得:本人当初学习STM32的时候有一些跟风的因素,自以为学的芯片越多就 ...

  7. Cordova打包Apk

    ======================== apk打包 ======================== keytool -genkey -v -keystore release-key.key ...

  8. Java之事务的基本应用

    基本介绍 事务是数据一致性最基本的保证,也就是说一个事务中的操作要么都成功,要么都失败,不允许部分成功.我们常说的事务就是jdbc事务,当然Java中还有其他事务,并且在使用jdbc事务有很多注意点, ...

  9. Docker入门1------概念和安装

    关于docker的介绍: https://www.cnblogs.com/neptunemoon/p/6512121.html docker入门教程:http://www.docker.org.cn/ ...

  10. Ethzasl MSF源码阅读(2):百川汇海

    这里有个感觉,就是百川汇海.即IMU数据和相机的消息数据都汇集到msf_core进行处理.接上一篇, 1. 查看IMUHandler_ROS::IMUCallback和IMUHandler_ROS:: ...