Java中this的用法

我们都知道执行一个方法的时候,要用object.method(argument list)。这种写法符合面向对象编程的特点:将信息输入到一个实例化的对象(object)里面。实际上这种写法纯粹是为了体现面向对象编程而作出的调整,程序实际执行的时候是这样:class.method(object, argument list),即对class调用方法,reference(object)和argument list是变量,它俩作为变量输入进class.method里面。注意:Java里面不允许按照后者风格来写。

由此可以看出一点,每当调用方法(non-static)的时候,除了argument list以外,还必须明确传达reference,不然机器不知道到底要操作哪一个object。注意:static方法由于不牵扯具体的object,所以不需要手动给reference,程序自动就给加上了。

当我们实例化一个对象的时候(new一个啥),我们可以用一个代号保存一下指向这个object的reference。注意:new Class()实际上就是个reference,前面的代号就表示以后我们可以凭此找到该reference(如果不用代号保存这些reference以后就接触不到了,因此导致无法直接操作其指向的object)。实例化以后,代号表示reference,再加上argument list,我们可以用面向对象风格的语言,执行方法。没毛病。

但如果我们想在class层面上(未实例化之前),使用未来的reference做些事情,如何解决?

解决方法是this,this正是未来object的reference。例如:

public class Apricot
{
    void pick() {}
    void pit() { pick(); }
}

第一个函数好说,实例化以后的reference(假设叫a)加argument 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("Yummy");
    }
 }

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

除此之外,多个constructor互相调用的时候必须用this,argument list名称与field重合时,需要用this加以区分(不重合加不加均可):

public class Flower
{
    int petalCount = 0;
    String s = "Initial value";

    Flower(int petals)
    {
        petalCount = petals;
        System.out.println("Constructor w/ int arg only, petalCount = " + petalCount);
    }

    Flower(String ss)
    {
        System.out.println("Constructor w/ String arg only, petalCount = " + ss);
        //输入变量的名称与filed不相符,因此不用必须加this。
        s = ss;
    }

    Flower(String s, int petals)
    {
        this(petals);
        //! this(s); Can't call two!
        //输入变量的名称与filed一样,为避免混淆,使用this。
        this.s = s;
        System.out.println("String & int args");
    }

    Flower()
    {
        this("hi", 47);
        System.out.println("default constructor, (no args) ");
    }

    void printPetalCount()
    {
        //! this(11); Not inside non-constructor!
        System.out.println("petalCount = " + petalCount + " s = " + s);
    }

    public static void main(String[] args)
    {
        Flower x = new Flower();
        x.printPetalCount();
    }
}

输出结果:

Constructor w/ int arg only, petalCount = 47
String & int args
default constructor, (no args) 
petalCount = 47 s = hi

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值