浅谈Java中的this作为返回值时返回的是什么

 更新时间:2017年11月10日 09:07:25   作者:蝉蝉  
Java中的this作为返回值时返回的是什么?下面小编就为大家介绍一下Java中的this作为返回值时返回。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

有时会遇到this作为返回值的情况,那么此时返回的到底是什么呢?

返回的是调用this所处方法的那个对象的引用,读起来有点绕口哈,有没有想起小学语文分析句子成份的试题,哈哈。

一点点分析的话,主干是“返回的是引用”;

什么引用呢?“那个对象的引用”;

哪个对象呢?“调用方法的那个对象”;

调用的哪个方法呢?“调用的是this所位于的方法”;这样就清楚了。

再总结一下就是,this作为返回值时,返回的是调用某方法的对象的引用,这个方法正是包含“return this;”这行命令的那个方法;更简单点说,就是谁调用返回的就是谁。

为了更清楚、直观的理解问题,下面以简单的例子说明。

包human中定义了Person类,代码如下:

package human;

public class Person {
 String name;
 int age;
 
 public Person() {
  
 }
 public Person(String n, String g) {
  name = n;
  gender = g;
 }

 
 //test:this作返回值
 Person reThis1() {
  Person per = new Person("lu","female");
  System.out.println("reThis1 per:" + per.name);
  return this;
 }
 Person reThis2() {
  Person per = reThis1();
  System.out.println("reThis2 per:" + per.name);
  return this;
 }
 Person reThis3() {
  name = "ma";
  return this;
 }
 static void equRefer(Person per1, Person per2) {
  if(per1 == per2)
   System.out.println("per1指向的对象没有改变,仍与per2指向同一个对象");
  else
   System.out.println("per1指向的对象已改变,与per2指向不同的对象");
  System.out.println("per1:" + per1.name);
  System.out.println("per2:" + per2.name);
 }
 
 public static void main(String[] args) {
  Person per1 = new Person("liu","female");
  Person per2 = per1;
  
  per1 = per1.reThis1();
  Person.equRefer(per1, per2);
   
  per1 = per1.reThis2();
  Person.equRefer(per1, per2);
  
  System.out.println("调用reThis3之前,per1.name=" + per1.name);
  per1 = per1.reThis3();
  System.out.println("调用reThis3之后,per1.name=" + per1.name);
 }
}

输出结果如下:

reThis1 per:lu
per1指向的对象没有改变,仍与per2指向同一个对象
per1:liu
per2:liu
reThis1 per:lu
reThis2 per:liu
per1指向的对象没有改变,仍与per2指向同一个对象
per1:liu
per2:liu
调用reThis3之前,per1.name=liu
调用reThis3之后,per1.name=ma

逐句分析执行过程:

(1).第1句:Person per1 = new Person("liu","female");

创建一个Person对象,将name初始化为“liu”,gender初始化为“female”,并让per1指向该对象。

(2).第2句:Person per2 = per1;

定义一个Person类的对象引用,并与per1指向同一个对象;具体内存分配见图1:

(3).第3句:per1 = per1.reThis1();

由per1调用reThis1()方法,并将返回值赋给per1;reThis1()方法体内定义了一个局部变量per,并创建一个对象,由per指向它;具体内存分配见图2:

紧接着输出reThis1 per:lu;最后返回this,并把返回的值赋给per1。

(4).第4句:Person.equRefer(per1, per2);

调用equRefer(per1,per2)来验证per1的值并未改变;根据下面的输出结果也可知per1仍与per2指向原来的对象,也就是说此时this的值与per1的值是一致的;也可以说,谁调用的返回的就是谁。

输出结果:

per1指向的对象没有改变,仍与per2指向同一个对象
per1:liu
per2:liu

此时的内存图如图3:

(5).第5句:per1 = per1.reThis2();

per1调用reThis2(),由(4)可推测,此时per1的值也不会变,是由per1调用的this所处的方法,所以返回的也是per1;具体来分析的话,reThis2()定义了一个局部变量per,并给其赋值为reThis1(),也就是说reThis2()调用了reThis1(),由(3)、(4)可推知,此时的内存结构是下面这样的:

局部变量per指向的对象与per1是一致的,因为调用reThis1的对象是per1所指的对象,所以返回值也是per1。

此处的输出结果为:

reThis1 per:lu
reThis2 per:liu

(6).第6句:Person.equRefer(per1, per2);

验证上面的结论,per1指向没变,此时的内存分配图如图4所示:

(7).第7、8、9句:

System.out.println("调用reThis3之前,per1.name=" + per1.name);
per1 = per1.reThis3();
System.out.println("调用reThis3之后,per1.name=" + per1.name);

per1调用reThis3();reThis3()中修改了namer的值,由"liu"改为"ma",然后返回this。

调用前后的内存结构分别如图6、图7所示:

输出结果:

调用reThis3之前,per1.name=liu
调用reThis3之后,per1.name=ma

再一次验证了上述的结论。

关于为什么使用this,我是这么理解的:由于定义类的时候尚未创建对象,所以不能确定对象到底叫什么,就用this来统一表示,等到具体调用时就可以知道对象的名字了,然后就用对象的引用替换this;所以为了便于记忆,可以理解成谁调用返回的就是谁。

至于返回this有什么意义,我的理解是:记返回this的方法为A,可能A的方法体中对对象的属性做了某些操作或调用了某些方法完成了某些动作,总之,做完这些操作后就把原对象的引用返回,返回后的状态是对象最新的状态,可能与对象调用方法A前不同。

以上这篇浅谈Java中的this作为返回值时返回的是什么就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java常见报错及解决方案总结

    java常见报错及解决方案总结

    这篇文章主要介绍了Java编程中常见错误类型及示例,包括语法错误、空指针异常、数组下标越界、类型转换异常、文件未找到异常、除以零异常、非法线程操作异常、方法未定义异常、死锁和类未找到异常,文中通过代码将解决方案介绍的非常详细,需要的朋友可以参考下
    2025-03-03
  • SpringBoot3集成MyBatis详解

    SpringBoot3集成MyBatis详解

    MyBatis是一款开源的持久层框架,它极大地简化了与数据库的交互流程,MyBatis更具灵活性,允许开发者直接使用SQL语句与数据库进行交互,本文将详细介绍在Spring Boot项目中如何集成MyBatis,以实现对数据库的轻松访问和操作,需要的朋友可以参考下
    2023-12-12
  • JAVA对象和字节数组互转操作

    JAVA对象和字节数组互转操作

    这篇文章主要介绍了JAVA对象和字节数组互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • idea版本控制忽略.idea文件和.iml文件的问题

    idea版本控制忽略.idea文件和.iml文件的问题

    这篇文章主要介绍了idea版本控制忽略.idea文件和.iml文件,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • spring MVC cors跨域实现源码解析

    spring MVC cors跨域实现源码解析

    本文主要介绍了spring MVC cors跨域实现源码解析。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • Mybatis-Plus中分页插件PaginationInterceptor的使用

    Mybatis-Plus中分页插件PaginationInterceptor的使用

    我们在开发的过程中,经常会遇到分页操作,本文主要介绍了Mybatis-Plus中分页插件PaginationInterceptor的使用,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • Data Source与数据库连接池简介(JDBC简介)

    Data Source与数据库连接池简介(JDBC简介)

    DataSource是作为DriverManager的替代品而推出的,DataSource 对象是获取连接的首选方法,这篇文章主要介绍了Data Source与数据库连接池简介(JDBC简介),需要的朋友可以参考下
    2022-11-11
  • Spring-boot 中@Async使用遇到的坑

    Spring-boot 中@Async使用遇到的坑

    这篇文章主要介绍了Spring-boot 中@Async使用的坑,首先使用@Async 需要在Spring启动类上添加注解@EnableAsyn或者在你们线程池配置类添加@EnableAsyn,需要的朋友可以参考下
    2024-01-01
  • springcloud集成nacos 使用lb 无效问题解决方案

    springcloud集成nacos 使用lb 无效问题解决方案

    这篇文章主要介绍了解决springcloud集成nacos 使用lb 无效,通过查看spring-cloud-starter-gateway jar中的自动配置类的源码,得知,该jar包中是不支持负载均衡的,需要引入spring-cloud-starter-loadbalancer 来支持,需要的朋友可以参考下
    2023-04-04
  • Struts2+Hibernate实现数据分页的方法

    Struts2+Hibernate实现数据分页的方法

    这篇文章主要介绍了Struts2+Hibernate实现数据分页的方法,结合实例形式分析了Struts2结合Hibernate实现数据分页的原理,步骤与相关实现代码,需要的朋友可以参考下
    2016-03-03

最新评论