java必学必会之this关键字_java

一、this关键字

  

this是一个引用,它指向自身的这个对象。

看内存分析图:

  假设我们在堆内存new了一个对象,在这个对象里面你想象着他有一个引用this,this指向这个对象自己,所以这就是this,这个new出来的对象名字是什么,我们不知道,不知道也没关系,因为这并不影响这个对象在内存里面的存在,这个对象只要在内存中存在,他就一定有一个引用this。

看下面的例子分析:

package cn.galc.test;

public class Leaf {

  int i = 0;

  public Leaf(int i) {
    this.i = i;
  }

  Leaf increament() {
    i++;
    return this;
  }

  void print() {
    System.out.println("i = " + i);
  }

  public static void main(String[] args) {
    Leaf leaf = new Leaf(100);
    leaf.increament().increament().print();
  }
}

在内存中分析main方法的执行过程

首先分析第一句话:Leaf leaf = new Leaf(100);

  程序执行到这里的时候,栈空间里面有一个变量leaf,它指向了我们new出来的在堆空间里面的Leaf对象。new这个Leaf对象的时候,调用了构造方法Leaf(),这个构造方法里面有一个形参i,所以在栈空间里面给构造方法分配有一小块内存,名字叫i用来装传递过来的实参。这里传过来的实参是100,所以i里面装的值就是100。得到这个值之后,构造方法继续执行,执行this.i = i;这里就是把栈空间里面的i的值通过值传递给Leaf对象里面的成员变量i,所以成员变量i的值也变成了100。内存中的布局如下图所示:

  

  构造方法执行完之后,为这个构造方法分配的内存消失,所以栈里面的i所标记的那一小块内存会消失。因此第一句话执行完之后,内存中的布局如下图所示:

  

接下来分析第二句话:leaf.increament().increament().print();

  首先逐个分析:leaf.increament(),这里是调用increament()方法,是对new出来的那个Leaf对象调用的,leaf是Leaf对象的引用对象,因此通过这个引用对象来调用increament()方法,即相当于是Leaf对象自己调用了increament()方法。increament()方法的定义如下:

Leaf increament(){
  i++;
  return this;

}

  因此Leaf对象调用increament()方法时,首先执行方法体里面的第一句话i++;这样就把Leaf对象的成员变量i的值由原来的100变成了101。此时的内存布局如下图所示。

  接下来执行方法体里面的第二句话:return this;

  这里把this作为返回值,当有返回值的时候,首先会在栈里面给这个返回值分配一小块临时的存储空间。这块存储空间里面的内容是this里面的内容。this指向它自身,所以栈内存里面的那块临时存储空间里面装的this也是指向堆内存里面的Leaf对象。

所以leaf.increament().increament().print();这句话里面的left.increament()这一小句话执行完之后,内存中的布局如下图所示。

  

  leaf.increament().increament().print();这句话里面的left.increament()这一小句话执行完之后,返回一个this,此时leaf.increament().increament().print();就相当于是this.increament().print();

  接着栈里面的存储在临时空间里面的this调用increament()方法,而this指的就是Leaf对象,所以又是Leaf对象调用increament()方法。Leaf对象调用increament()方法时,又会执行方法体里面的i++,所以此时i又由原来的101变成了102。然后又执行return this,所以栈内存里面又多了一块临时存储空间,里面装的值也是this,这个this又是指向堆内存里面的Leaf对象。因此此时这个Leaf对象有了四个指向他自己的引用对象。

  leaf.increament().increament().print();这句话里面的leaf.increament().increament()这一小句话执行完之后,都返回了一个this,所以此时的leaf.increament().increament().print();就相当于是这样子的:this.this.print();

  接下来又是栈里面的那个新的this调用print()方法,使用this来调用,那就相当于是Leaf对象来调用,Leaf对象自己调用print()方法将自己的i属性的值打印出来,所以打印出来的结果应该是102。

  因此main方法里面的整个程序执行完之后,内存中的布局如下图所示:

  

  this的总结:this一般出现在方法里面,当这个方法还没有调用的时候,this指的是谁并不知道。但是实际当中,你如果new了一个对象出来,那么this指的就是当前这个对象。对哪个对象调用方法,this指的就是调用方法的这个对象(你对哪个对象调用这个方法,this指的就是谁)。如果再new一个对象,这个对象他也有自己的this,他自己的this就当然指的是他自己了。

以图文相结合的方式为大家详细介绍java this关键字,希望能够帮助到大家更好地理解this关键字。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
this关键字
java this关键字、java this关键字详解、java 的this关键字、java中的this关键字、java中this关键字,以便于您获取更多的相关知识。

时间: 2024-10-24 09:08:48

java必学必会之this关键字_java的相关文章

java必学必会之线程(2)_java

一.线程的优先级别 线程优先级别的使用范例: package cn.galc.test; public class TestThread6 { public static void main(String args[]) { MyThread4 t4 = new MyThread4(); MyThread5 t5 = new MyThread5(); Thread t1 = new Thread(t4); Thread t2 = new Thread(t5); t1.setPriority(Th

java必学必会之static关键字_javascript技巧

一.static关键字 原来一个类里面的成员变量,每new一个对象,这个对象就有一份自己的成员变量,因为这些成员变量都不是静态成员变量.对于static成员变量来说,这个成员变量只有一份,而且这一份是这个类所有的对象共享. 1.1.静态成员变量与非静态成员变量的区别 以下面的例子为例说明 package cn.galc.test; public class Cat { /** * 静态成员变量 */ private static int sid = 0; private String name;

java必学必会之线程(1)_java

一.线程的基本概念 线程理解:线程是一个程序里面不同的执行路径 每一个分支都叫做一个线程,main()叫做主分支,也叫主线程. 程只是一个静态的概念,机器上的一个.class文件,机器上的一个.exe文件,这个叫做一个进程.程序的执行过程都是这样的:首先把程序的代码放到内存的代码区里面,代码放到代码区后并没有马上开始执行,但这时候说明了一个进程准备开始,进程已经产生了,但还没有开始执行,这就是进程,所以进程其实是一个静态的概念,它本身就不能动.平常所说的进程的执行指的是进程里面主线程开始执行了,

java必学必会之网络编程_java

一.网络基础概念 首先理清一个概念:网络编程 != 网站编程,网络编程现在一般称为TCP/IP编程. 二.网络通信协议及接口 三.通信协议分层思想 四.参考模型 五.IP协议 每个人的电脑都有一个独一无二的IP地址,这样互相通信时就不会传错信息了. IP地址是用一个点来分成四段的,在计算机内部IP地址是用四个字节来表示的,一个字节代表一段,每一个字节代表的数最大只能到达255. 六.TCP协议和UDP协议 TCP和UDP位于同一层,都是建立在IP层的基础之上.由于两台电脑之间有不同的IP地址,因

java必学必会之方法的重载(overload)_java

一.方法的重载 方法名一样,但参数不一样,这就是重载(overload). 所谓的参数不一样,主要有两点:第一是参数的个数不一样,第二是参数的类型不一样.只要这两方面有其中的一方面不一样就可以构成方法的重载了. package cn.galc.test; public class TestOverLoad { void max(int a, int b) { System.out.println(a > b ? a : b); } /* * int max(int a, int b) { * r

java必学必会之equals方法_java

一.equals方法介绍 1.1.通过下面的例子掌握equals的用法 package cn.galc.test; public class TestEquals { public static void main(String[] args) { /** * 这里使用构造方法Cat()在堆内存里面new出了两只猫, * 这两只猫的color,weight,height都是一样的, * 但c1和c2却永远不会相等,这是因为c1和c2分别为堆内存里面两只猫的引用对象, * 里面装着可以找到这两只猫

java必学必会之GUI编程_java

一.事件监听 测试代码一: package cn.javastudy.summary; import java.awt.*; import java.awt.event.*; public class TestTextField { public static void main(String args[]) { new MyFrameTextField(); } } class MyFrameTextField extends Frame { MyFrameTextField() { Text

java多线程编程之慎重使用volatile关键字_java

volatile关键字相信了解Java多线程的读者都很清楚它的作用.volatile关键字用于声明简单类型变量,如int.float.boolean等数据类型.如果这些简单数据类型声明为volatile,对它们的操作就会变成原子级别的.但这有一定的限制.例如,下面的例子中的n就不是原子级别的: 复制代码 代码如下: package mythread; public class JoinThread extends Thread{public static volatile int n = 0;p

前端必学之PHP语法基础_php实例

写在前面的话 PHP是一种创建动态交互性站点的强有力的服务器端脚本语言.PHP能够包含文本.HTML.CSS以及PHP代码,在服务器上执行,结果以纯文本返回浏览器 代码标识 PHP代码以<?php 开头,以?>结尾,且可以放置在文档中的任何位置 <?php // ?> PHP语句以分号(;)结尾,PHP代码块的关闭标签也会自动表明分号 <?php echo "Hello World!"; ?> 注释 PHP支持三种注释,包括两种单行注释和一种多行注释