疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

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);
    }
}
复制代码
 
 
输出结果如下:
 
复制代码
 1 reThis1 per:lu
 2 per1指向的对象没有改变,仍与per2指向同一个对象
 3 per1:liu
 4 per2:liu
 5 reThis1 per:lu
 6 reThis2 per:liu
 7 per1指向的对象没有改变,仍与per2指向同一个对象
 8 per1:liu
 9 per2:liu
10 调用reThis3之前,per1.name=liu
11 调用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前不同。