ThinkingInJava对this关键字的介绍

this 关键字

如果有两个同类型的对象,分别叫作a 和b,那么您也许不知道如何为这两个对象同时调用一个 f()方法:

class Banana { void f(int i) { /* ... */ } }
Banana a = new Banana(), b = new Banana();
a.f(1);
b.f(2);

若只有一个名叫f()的方法,它怎样才能知道自己是为 a 还是为 b 调用的呢?
为了能用简便的、面向对象的语法来书写代码——亦即“将消息发给对象”,编译器为我们完成了一些幕后
工作。其中的秘密就是第一个自变量传递给方法f(),而且那个自变量是准备操作的那个对象的句柄。所以
前述的两个方法调用就变成了下面这样的形式:

Banana.f(a,1);
Banana.f(b,2);

这是内部的表达形式,我们并不能这样书写表达式,并试图让编译器接受它。但是,通过它可理解幕后到底
发生了什么事情。

假定我们在一个方法的内部,并希望获得当前对象的句柄。由于那个句柄是由编译器“秘密”传递的,所以
没有标识符可用。然而,针对这一目的有个专用的关键字:this。this 关键字(注意只能在方法内部使用)
可为已调用了其方法的那个对象生成相应的句柄。可象对待其他任何对象句柄一样对待这个句柄。但要注
意,假若准备从自己某个类的另一个方法内部调用一个类方法,就不必使用this。只需简单地调用那个方法
即可。当前的this 句柄会自动应用于其他方法。所以我们能使用下面这样的代码:

class Apricot {
void pick() { /* ... */ }
void pit() { pick(); /* ... */ }
}

在pit()内部,我们可以说 this.pick(),但事实上无此必要。编译器能帮我们自动完成。this 关键字只能
用于那些特殊的类——需明确使用当前对象的句柄。例如,假若您希望将句柄返回给当前对象,那么它经常
在return 语句中使用。

//: Leaf.java
// Simple use of the "this" keyword
public class Leaf {private int i = 0;Leaf increment() {i++;return this;}void print() {System.out.println("i = " + i);}public static void main(String[] args) {Leaf x = new Leaf();x.increment().increment().increment().print();}
} ///:~

由于increment()通过 this 关键字返回当前对象的句柄,所以可以方便地对同一个对象执行多项操作。
1. 在构建器里调用构建器
若为一个类写了多个构建器,那么经常都需要在一个构建器里调用另一个构建器,以避免写重复的代码。可
用this 关键字做到这一点。
通常,当我们说this 的时候,都是指“这个对象”或者“当前对象”。而且它本身会产生当前对象的一个句
柄。在一个构建器中,若为其赋予一个自变量列表,那么 this 关键字会具有不同的含义:它会对与那个自变
量列表相符的构建器进行明确的调用。这样一来,我们就可通过一条直接的途径来调用其他构建器。如下所
示:

//: Flower.java
// Calling constructors with "this"
public class Flower {private int petalCount = 0;private String s = new String("null");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, s=" + ss);s = ss;}Flower(String s, int petals) {this(petals);
//! this(s); // Can't call two!this.s = s; // Another use of "this"System.out.println("String & int args");}Flower() {this("hi", 47);System.out.println("default constructor (no args)");}void print() {
//! this(11); // Not inside non-constructor!System.out.println("petalCount = " + petalCount + " s = "+ s);}public static void main(String[] args) {Flower x = new Flower();x.print();}
} ///:~

其中,构建器Flower(String s,int petals)向我们揭示出这样一个问题:尽管可用this 调用一个构建器,
但不可调用两个。除此以外,构建器调用必须是我们做的第一件事情,否则会收到编译程序的报错信息。
这个例子也向大家展示了this 的另一项用途。由于自变量s 的名字以及成员数据s 的名字是相同的,所以会
出现混淆。为解决这个问题,可用 this.s 来引用成员数据。经常都会在 Java 代码里看到这种形式的应用,
本书的大量地方也采用了这种做法。
在print()中,我们发现编译器不让我们从除了一个构建器之外的其他任何方法内部调用一个构建器。

个人总结:

  1. this关键字必须写在构造方法内部

    在构造函数中,如果你不指定构造器之间的调用关系,那么编译器会给你加上super();目的是在初始化当前对象时,先保证了父类对象先初始化。所以,你指定了构造函数间的调用,那么this()必须在第一行,以保证在执行任何动作前,对象已经完成了初始化。
    构造函数只能被构造函数调用,因为对象只会初始化一次。

  2. 构造方法调用语句放在第一

    为了避免构建出两个对象这种问题的出现,Java在编译时对这种情况做了强校验,用户不能再同一个方法内调用多次this()或super(),同时为了避免对对象本身进行操作时,对象本身还未构建成功(也就找不到对应对象),所以对this()或super()的调用只能在构造方法中的第一行实现,防止异常。

  3. 在构造方法内部,只能调用一个构造方法

    类似this()和super()这样的方法被称为构造方法,顾名思义,他的作用就是在JVM堆中构建出一个指定类型的对象,如果你调用了两个这种形式的方法,岂不是代表着构建出了两个对象。

  4. 非构造方法不能在方法内部调用构造方法

    在普通的成员方法中,如果调用super()或者this(),你是想要重新创建一个对象吗?抱歉Java为了保证自身对象的合理性,不允许你做这样的操作。

参考文章
http://blog.csdn.net/lsly521/article/details/52243783

转载于:https://www.cnblogs.com/aotemanzhifu/p/9192425.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/487222.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

集成电路将成一级学科,这些高校迎来重大机遇!

来源:软科8月4日,国务院发布关于印发《新时期促进集成电路产业和软件产业高质量发展的若干政策》的通知。《新时期促进集成电路产业和软件产业高质量发展的若干政策》在人才政策这一项中提到:进一步加强高校集成电路和软件专业建设&#xff0…

震撼三观:从细胞到宇宙

这是一次高速旅行,每次都以10倍的速度跳跃。从 10的0次方开始(也就是1 米), 然后每次按照10的乘方增加。从10米, 100 米, 1000米,以此类推, 直至巨视世界的无尽。来源:通往知识之路(ID:tongwang…

关于ZipOupputStream添加压缩包常见问题

其实园子压缩解压缩的方法很多,ZipOupputStream这个类的说明很多,我这边也是从网上找的代码,但是我在压缩的时候遇到了常见的两个问题,第一个就是压缩的时候读取压缩包报该压缩包已经在另一个进程打开的bug,这个问题解…

边缘AI芯片市场将在2025年首次反超云端AI芯片市场

边缘AI将利用许多其他新兴技术,为消费者和企业领域的各种新商机铺平道路。来源:雷锋网作者:吴优由于市场对低延迟、数据隐私以及低成本和超节能的可用性的日益关注,预计到2025年,边缘AI芯片组市场将首次超过云AI芯片组…

性能指标分析

文章:架构必会的性能指标及分析策略转载于:https://www.cnblogs.com/Tpf386/p/7904174.html

倪光南:看好鸿蒙系统,坚持生态体系创新才能不被“卡脖子”

图为倪光南院士接受专访来源:澎湃新闻8月7日,在中国信息化百人会2020年峰会上,华为消费者业务CEO余承东关于“麒麟芯片将绝版”的消息一石激起千层浪,在新的国际环境下,国内科技企业应当如何突破重围,自主创…

弦理论三先驱获2020年狄拉克奖

狄拉克奖是国际理论物理中心(International Centre for Theoretical Physics,ICTP)为纪念理论物理学家狄拉克而在1985年设置的奖项,被视为理论和数学物理领域的最高荣誉之一。近日,ICTP 在意大利 Trieste 宣布了2020年…

windows c++ 内存映射大文件问题记录

MapViewOfFile()使用时总是报错1132,是因为起始位置大小要是64k的倍数。 例如:LPVOID pFileBlock MapViewOfFile(OpenMap , FILE_MAP_ALL_ACCESS // 注意,和createfile要一致 , 0 , dBegin …

CCAI 2020 | 黄铁军:“仿真主义”下的人工智能发展之路

来源:中国人工智能学会在人工智能发展的60多年中,大致有四种方法来实现某些人工智能:符号主义,联结主义,行为主义和统计学,它们分别从不同的角度抓住了“智能”的一些特点,因此各自引领着一个时…

对new int[]()的理解(转载)

new(多个对象)数组 new分配的对象,不管单个对象还是多个对象的分配,都是默认初始化。但可以对数组进行值初始化,方法就是:在大小之后添加一对空括号。 int *p1 new int[10]; // 10个未初始化int int *p2 new int[10](); // …

事件(二):事件处理程序

click,load,mouseover都是事件的名字,而响应某个事件的函数就叫做事件处理程序(或事件侦听器)。事件处理程序的名字以on开头,onclick,onload 事件处理程序(html事件处理程序,dom0级事件处理程序&#xff0c…

物联网激荡MEMS传感器浪潮

来源:第三代半导体联合创新孵化中心物联网悄然而至。如今,物联网已进入跨界融合、集成创新和规模化发展新阶段,将为经济社会发展注入新活力,培育新动能。物联网在交通、物流、环保、医疗、安防、电力等领域的应用逐渐得到规模化验…

如何判断是linux/windows库,module或程序debug还是release(转)

linux: readelf -S xxx.a |grep "\.debug*" 如果有输出, 是debug, 没有是release windows: dumpbin /DEPENDENTS xx.dll, 结果输出中有MSVCRTD.dll的是debug版本. 为了脚本自动判断, 可用powergrep等工具自动分拣. .lib和我们的编译选项有…

发布功能完成。

编写要求登录的装饰器from functools import wraps def loginFirst(func): #参数是函数 wraps(func) def wrapper(*args, ** kwargs): #定义个函数将其返回 #要求登录 return func(*args, ** kwargs) return wrapper #返回一个函数 应用装饰器,要求在发布前进行登录…

git clone报错

问题:error: RPC failed; curl 18 transfer closed with outstanding read data remaining 方法:(一般http方式会用到) $ git clone 仓库地址 --depth 1 $ cd 项目目录 $ git fetch --unshallow 附带:指定分支命令 …

《自然》《科学》相继发文批评质疑:俄罗斯注册新冠疫苗“让众人面临风险”...

来源:环球科学编译丨杨心舟8月11日,俄罗斯总统普京在与政府成员举行会议时透露,俄罗斯已经注册世界第一种新冠肺炎疫苗。普京表示,这款疫苗非常有效,能够形成稳定的免疫力并且已通过所有的检查,并且自己的女…

翻译连载 | 附录 A:Transducing(下)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇...

原文地址:Functional-Light-JS原文作者:Kyle Simpson-《You-Dont-Know-JS》作者关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTML 最坚实的梁柱;分享,是 CSS 里最闪耀的一瞥…

python 去除不可见字符\x00

读取出来的字节:testa b‘testa\x00’ 去掉\x00:testa.decode().strip(b\x00.decode()) 经测试多个\x00也可以去掉

思未尽,行致远丨记 IBM 成立 109周年

来源:IBM中国主创团队(IBM Social & Studio DL team)策划:点亮 IBM 庆生蜡烛的甜心御姐 June撰稿:被百年“名场面”感动 cry 的原创一哥 Raphal设计:熬出黑眼圈也要操刀设计的鲁先森排版:话…

RAC(ReactiveCocoa)使用方法(二)

RAC(ReactiveCocoa)使用方法(一)RAC(ReactiveCocoa)使用方法(二) 上篇文章:RAC(ReactiveCocoa)使用方法(一) 中主要介绍了一些RAC中常见类的用法,这篇文章主要总结日常开发中结合一些UI控件的用法。 RAC给常见的很多UI类拓展了用法,使得开发变得越来越简…