对象的this引用

 类本身的方法调用类的其他方法

Java提供了一个this关键字,this关键字总是指向调用该方法的对象。根据this出现位置的不同,this作为对象的默认引用有两种情 形。
构造器中引用该构造器正在初始化的对象。
在方法中引用调用该方法的对象。
this关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或实例变量。假设定义了一个Dog类,这个Dog对象的run()方法 需要调用它的jump()方法,那么应该如何做?是否应该定义如下的Dog 类呢?
使用这种方式来定义这个Dog类,确实可以实现在run()方法中调用jump()方法。那么这种做法是否够好呢?下面再提供一个程序来创 建Dog对象,并调用该对象的run()方法。 

在上面的程序中,一共产生了两个Dog对象,在Dog类的run()方法中,程序创建了一个Dog对象,并使用名为d的引用变量来指向该Dog对 象;在DogTest的main()方法中,程序再次创建了一个Dog对象,并使 用名为dog的引用变量来指向该Dog对象。 这里产生了两个问题。第一个问题:在run()方法中调用jump()方 法时是否一定需要一个Dog对象?第二个问题:是否一定需要重新创建
一个Dog对象?第一个问题的答案是肯定的,因为没有使用static修饰的成员变量和方法都必须使用对象来调用。第二个问题的答案是否定 的,因为当程序调用run()方法时,一定会提供一个Dog对象,这样就 可以直接使用这个已经存在的Dog对象,而无须重新创建新的Dog对象 了。因此需要在run()方法中获得调用该方法的对象,通过this关键字 就可以满足这个要求。 this可以代表任何对象,当this出现在某个方法体中时,它所代 表的对象是不确定的,但它的类型是确定的:它所代表的只能是当前 类的实例;只有当这个方法被调用时,它所代表的对象才被确定下 来:谁在调用这个方法,this就代表谁。 将前面的Dog类的run()方法改为如下形式会更加合适。 
采用上面方法定义的Dog类更符合实际意义。从前一种Dog类定义来看,在Dog对象的run()方法内重新创建了一个新的Dog对象,并调用 它的jump()方法,这意味着一个Dog对象的run()方法需要依赖于另一 个Dog对象的jump()方法,这不符合逻辑。上面的代码更符合实际情 形:当一个Dog对象调用run()方法时,run()方法需要依赖它自己的 jump()方法。 在现实世界里,对象的一个方法依赖于另一个方法的情形如此常 见:例如,吃饭方法依赖于拿筷子方法,写程序方法依赖于敲键盘方
法,这种依赖都是同一个对象两个方法之间的依赖。因此,Java允许对象的一个成员直接调用另一个成员,可以省略this前缀。也就是 说,将上面的run()方法改为如下形式也完全正确

 

大部分时候,一个方法访问该类中定义的其他方法、成员变量时加不加this前缀的效果是完全一样的。 对于static修饰的方法而言,则可以使用类来直接调用该方法, 如果在static修饰的方法中使用this关键字,则这个关键字就无法指 向合适的对象。所以,static修饰的方法中不能使用this引用。由于 static修饰的方法不能使用this引用,所以static修饰的方法不能访 问不使用static修饰的普通成员,因此Java语法规定:静态成员不能 直接访问非静态成员。
提示:
省略this前缀只是一种假象,虽然程序员省略了调用jump()方法之前的this,但实际上这个this依然是存在的。根据汉语语法习 惯:完整的语句至少包括主语、谓语、宾语,在面向对象的世界 里,主、谓、宾的结构完全成立,例如“猪八戒吃西瓜”是一条汉 语语句,转换为面向对象的语法,就可以写成“猪八戒.吃(西 瓜);”,因此本书常常把调用成员变量、方法的对象称为“主调 (主语调用者的简称)”。对于Java语言来说,调用成员变量、方 法时,主调是必不可少的,即使代码中省略了主调,但实际的主调 依然存在。一般来说,如果调用static修饰的成员(包括方法、成 员变量)时省略了前面的主调,那么默认使用该类作为主调;如果 调用没有static修饰的成员(包括方法、成员变量)时省略了前面 的主调,那么默认使用this作为主调。

下面程序演示了静态方法直接访问非静态方法时引发的错误。 

 

编译上面的程序,系统提示在info();代码行出现如下错误: 

上面错误正是因为info()方法是属于实例的方法,而不是属于类的方法,因此必须使用对象来调用该方法。在上面的main()方法中直 接调用info()方法时,系统相当于使用this作为该方法的调用者,而 main()方法是一个static修饰的方法,static修饰的方法属于类,而 不属于对象,因此调用static修饰的方法的主调总是类本身;如果允 许在static修饰的方法中出现this引用,那将导致this无法引用有效 的对象,因此上面程序出现编译错误。
注意:
Java有一个让人极易“混淆”的语法,它允许使用对象来调用static修饰的成员变量、方法,但实际上这是不应该的。前面已经 介绍过,static修饰的成员属于类本身,而不属于该类的实例,既 然static修饰的成员完全不属于该类的实例,那么就不应该允许使 用实例去调用static修饰的成员变量和方法!所以请读者牢记一 点:Java编程时不要使用对象去调用static修饰的成员变量、方 法,而是应该使用类去调用static修饰的成员变量、方法!如果在 其他Java代码中看到对象调用static修饰的成员变量、方法的情 形,则完全可以把这种用法当成假象,将其替换成用类来调用 static修饰的成员变量、方法的代码。

局部变量与成员变量同名

大部分时候,普通方法访问其他方法、成员变量时无须使用this前缀,但如果方法里有个局部变量和成员变量同名,但程序又需要在 该方法里访问这个被覆盖的成员变量,则必须使用this前缀。
除此之外,this引用也可以用于构造器中作为默认引用,由于构造器是直接使用new关键字来调用,而不是使用对象来调用的,所以 this在构造器中代表该构造器正在初始化的对象。

在ThisInConstructor构造器中使用this引用时,this总是引用该构造器正在初始化的对象。程序中粗体字代码将正在执行初始化的 ThisInConstructor对象的foo成员变量设为6,这意味着该构造器返回
的所有对象的foo成员变量都等于6。 与普通方法类似的是,大部分时候,在构造器中访问其他成员变 量和方法时都可以省略this前缀,但如果构造器中有一个与成员变量 同名的局部变量,又必须在构造器中访问这个被覆盖的成员变量,则 必须使用this前缀。如上面的ThisInConstructor.java所示。 当this作为对象的默认引用使用时,程序可以像访问普通引用变 量一样来访问这个this引用,甚至可以把this当成普通方法的返回 值。
看下面程序:

从上面程序中可以看出,如果在某个方法中把this作为返回值,则可以多次连续调用同一个方法,从而使得代码更加简洁。但是,这 种把this作为返回值的方法可能造成实际意义的模糊,例如上面的 grow方法,用于表示对象的生长,即age成员变量的值加1,实际上不 应该有返回值。
注意:
使用this作为方法的返回值可以让代码更加简洁,但可能造成实际意义的模糊

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值