我们都知道执行一个方法的时候,要用object.method(type list)。这种写法符合面向对象编程的特点:将信息输入到一个实例化的对象(object)里面。实际上这种写法纯粹是为了体现面向对象编程而作出的调整,程序实际执行的时候是这样:class.method(object, type list),即对class调用方法,reference(object)和type list是变量,它俩作为变量输入进class.method里面。注意:Java里面不允许按照后者风格来写。
由此可以看出一点,每当调用方法(non-static)的时候,除了type list以外,还必须明确传达reference,不然机器不知道到底要操作哪一个object。注意:static方法由于不牵扯具体的object,所以不需要手动给reference,程序自动就给加上了。
当我们实例化一个对象的时候(new一个啥),我们可以用一个代号保存一下指向这个object的reference。注意:new Class()实际上就是个reference,前面的代号就表示以后我们可以凭此找到该reference(如果不用代号保存这些reference以后就接触不到了,因此导致无法直接操作其指向的object)。实例化以后,代号表示reference,再加上type list,我们可以用面向对象风格的语言,执行方法。没毛病。
但如果我们想在class层面上(未实例化之前),使用未来的reference做些事情,如何解决?
解决方法是this,this正是未来object的reference。例如:
public class Apricot { void pick() {} void pit() { pick(); } }
第一个函数好说,实例化以后的reference(假设叫a)加type list(本例无)俩条件可以解决。第二个函数pit()实例化后两条件也是一样,而pit()里面的pick()的reference是谁?很明显该reference也正是a,我们可以手动输入(用this.pick();),也可以不用(Java自会帮我们将其添加进去)。虽然这种情况下不推荐用this(但凡Java帮忙自动加的情况都不要手动this),但通过此例可以感觉到this的存在。
再看另外两个例子:
public class Leaf { int i = 0; Leaf increment() { i++; //返回的正是x代表的reference。 return this; } void print() { System.out.println("i = " + i); } public static void main(String[] args) { //实例化Leaf,x表示该实例(object)的reference。 Leaf x = new Leaf(); //4次调用方法,reference均是同一个。 x.increment().increment().increment().print(); } }
输出结果:
i = 3
另外一个例子:
class Person { public void eat(Apple eat) { //先将苹果剥皮。 Apple peeled = apple.getPeeled(); System.out.println("Yammy"); } } class Peerler { //static方法,可根据类名直接调用。 static Apple peel(Apple apple) { //其他代码指令,比如剥皮。 .... //返回已经“剥掉皮”的苹果。 return apple; } } class Apple { //this代表的正是实例化后Apple后的reference。该方法可看做将这个object放到Peeler类中的peel方法内过一遍再回来。 Apple getPeeled() { return Peeler.peel(this); } } public class PassingThis { public static void main(String[] args) { //两个reference没有被保存下来。 new Person.eat(new Apple); } }
返回结果:
Yummy