Java内部类详解成员内部类,局部内部类,匿名内部类,静态内部类安静的程序媛

说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉。原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法。今天我们就来一探究竟。下面是本文的目录大纲:

一.内部类基础

二.深入理解内部类

三.内部类的使用场景和好处

若有不正之处,请多谅解并欢迎批评指正。

请尊重作者劳动成果,转载请标明原文链接:

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就先来了解一下这四种内部类的用法。

1.成员内部类

成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:

这样看起来,类Draw像是类Circle的一个成员,Circle称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。

不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:

虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:

成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。创建成员内部类对象的一般方式如下:

内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。比如上面的例子,如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被public和包访问两种权限修饰。我个人是这么理解的,由于成员内部类看起来像是外部类的一个成员,所以可以像类的成员一样拥有多种权限修饰。

2.局部内部类

局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。

注意,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

3.匿名内部类

匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护。下面这段代码是一段Android事件监听代码:

这段代码为两个按钮设置监听器,这里面就使用了匿名内部类。这段代码中的:

就是匿名内部类的使用。代码中需要给按钮设置监听器对象,使用匿名内部类能够在实现父类或者接口中的方法情况下同时产生一个相应的对象,但是前提是这个父类或者接口必须先存在才能这样使用。当然像下面这种写法也是可以的,跟上面使用匿名内部类达到效果相同。

这种写法虽然能达到一样的效果,但是既冗长又难以维护,所以一般使用匿名内部类的方法来编写事件监听代码。同样的,匿名内部类也是不能有访问修饰符和static修饰符的。

匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

4.静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

1.为什么成员内部类可以无条件访问外部类的成员?

在此之前,我们已经讨论过了成员内部类可以无条件访问外部类的成员,那具体究竟是如何实现的呢?下面通过反编译字节码文件看看究竟。事实上,编译器在进行编译的时候,会将成员内部类单独编译成一个字节码文件,下面是Outter.java的代码:

编译之后,出现了两个字节码文件:

反编译Outter$Inner.class文件得到下面信息:

第11行到35行是常量池的内容,下面逐一第38行的内容:

finalcom.cxh.test2.Outterthis$0;这行是一个指向外部类对象的指针,看到这里想必大家豁然开朗了。也就是说编译器会默认为成员内部类添加了一个指向外部类对象的引用,那么这个引用是如何赋初值的呢?下面接着看内部类的构造器:

publiccom.cxh.test2.Outter$Inner(com.cxh.test2.Outter);从这里可以看出,虽然我们在定义的内部类的构造器是无参构造器,编译器还是会默认添加一个参数,该参数的类型为指向外部类对象的一个引用,所以成员内部类中的Outterthis&0指针便指向了外部类对象,因此可以在成员内部类中随意访问外部类的成员。从这里也间接说明了成员内部类是依赖于外部类的,如果没有创建外部类的对象,则无法对Outterthis&0引用进行初始化赋值,也就无法创建成员内部类的对象了。

2.为什么局部内部类和匿名内部类只能访问局部final变量?

想必这个问题也曾经困扰过很多人,在讨论这个问题之前,先看下面这段代码:

根据上图可知,test方法中的匿名内部类的名字被起为Test$1。

上段代码中,如果把变量a和b前面的任一个final去掉,这段代码都编译不过。我们先考虑这样一个问题:

当test方法执行完毕之后,变量a的生命周期就结束了,而此时Thread对象的生命周期很可能还没有结束,那么在Thread的run方法中继续访问变量a就变成不可能了,但是又要实现这样的效果,怎么办呢?Java采用了复制的手段来解决这个问题。将这段代码的字节码反编译可以得到下面的内容:

我们看到在run方法中有一条指令:

bipush10这条指令表示将操作数10压栈,表示使用的是一个本地局部变量。这个过程是在编译期间由编译器默认进行,如果这个变量的值在编译期间可以确定,则编译器默认会在匿名内部类(局部内部类)的常量池中添加一个内容相等的字面量或直接将相应的字节码嵌入到执行字节码中。这样一来,匿名内部类使用的变量是另一个局部变量,只不过值和方法中局部变量的值相等,因此和方法中的局部变量完全独立开。

下面再看一个例子:

反编译得到:

我们看到匿名内部类Test$1的构造器含有两个参数,一个是指向外部类对象的引用,一个是int型变量,很显然,这里是将变量test方法中的形参a以参数的形式传进来对匿名内部类中的拷贝(变量a的拷贝)进行赋值初始化。

也就说如果局部变量的值在编译期间就可以确定,则直接在匿名内部里面创建一个拷贝。如果局部变量的值无法在编译期间确定,则通过构造器传参的方式来对拷贝进行初始化赋值。

从上面可以看出,在run方法中访问的变量a根本就不是test方法中的局部变量a。这样一来就解决了前面所说的生命周期不一致的问题。但是新的问题又来了,既然在run方法中访问的变量a和test方法中的变量a不是同一个变量,当在run方法中改变变量a的值的话,会出现什么情况?

对,会造成数据不一致性,这样就达不到原本的意图和要求。为了解决这个问题,java编译器就限定必须将变量a限制为final变量,不允许对变量a进行更改(对于引用类型的变量,是不允许指向新的对象),这样数据不一致性的问题就得以解决了。

到这里,想必大家应该清楚为何方法中的局部变量和形参都必须用final进行限定了。

3.静态内部类有特殊的地方吗?

从前面可以知道,静态内部类是不依赖于外部类的,也就说可以在不创建外部类对象的情况下创建内部类的对象。另外,静态内部类是不持有指向外部类对象的引用的,这个读者可以自己尝试反编译class文件看一下就知道了,是没有Outterthis&0引用的。

为什么在Java中需要内部类?总结一下主要有以下四点:

1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整,

2.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。

3.方便编写事件驱动程序

4.方便编写线程代码

个人觉得第一点是最重要的原因之一,内部类的存在使得Java的多继承机制变得更加完善。

1.根据注释填写(1),(2),(3)处的代码

从前面可知,对于成员内部类,必须先产生外部类的实例化对象,才能产生内部类的实例化对象。而静态内部类不用产生外部类的实例化对象即可产生内部类的实例化对象。

创建静态内部类对象的一般形式为:外部类类名.内部类类名xxx=new外部类类名.内部类类名()

创建成员内部类对象的一般形式为:外部类类名.内部类类名xxx=外部类对象名.new内部类类名()

因此,(1),(2),(3)处的代码分别为:

2.下面这段代码的输出结果是什么?

最后补充一点知识:关于成员内部类的继承问题。一般来说,内部类是很少用来作为继承用的。但是当用来继承的话,要注意两点:

1)成员内部类的引用方式必须为Outter.Inner.

2)构造器中必须有指向外部类对象的引用,并通过这个引用调用super()。这段代码摘自《Java编程思想》

THE END
1.Double结构(System)MicrosoftLearnpublic readonly struct Double : IComparable<double>, IConvertible, IEquatable<double>, IParsable<double>, ISpanParsable<double>, IUtf8SpanParsable<double>, System.Numerics.IAdditionOperators<double,double,double>, System.Numerics.IAdditiveIdentity<double,double>, System.Numerics.IBinaryFloatingPointIeehttps://msdn.microsoft.com/zh-cn/library/system.double(VS.80).aspx
2.码上去学海南公司:C++VSC,深入解析两大编程语言的异同与优劣在编程的世界里,C和C++无疑是两颗璀璨的明星。它们之间既有深厚的渊源,又有着显著的差异。本文码上去学海南公司将带你深入探讨C++与C的区别,助你更好地掌握这两门语言。 C与C++的历史背景 C的起源 C语言诞生于1972年,由贝尔实验室的丹尼斯·里奇(Dennis Ritchie)设计,主要用于系统编程。 C++的诞生 C++则是在https://zhuanlan.zhihu.com/p/9714271767
3.使用double类型的问题精度问题:使用double类型来存储分数可使用double 类型的问题 精度问题: 使用 double 类型来存储分数可能会导致精度损失。尤其是当分子和分母的值非常大时,double 类型可能无法精确表示这些数值。 浮点比较问题: 浮点数的比较通常需要考虑一个小的误差范围。如果两个浮点数非常接近,直接使用等于操作符可能会导致错误的比较结果。 使用整数和最大公约数的优势https://www.nowcoder.com/discuss/comment/16598448?urlSource=sitemapApi
4.编程语言对比与选型语言是一种通用的编程语言,它广泛用于系统软件开发、嵌入式软件开发、游戏开发等领域。由于其高效的性能和对硬件的直接控制能力,C语言在对性能要求较高的场景中表现突出。例如,操作系统、驱动程序以及嵌入式系统等领域。由于C语言具有较高的灵活性和可移植性,它还被广泛应用于跨平台开发中。 https://www.jianshu.com/p/c77bb8b4ba2a
5.andcompromisesinthecareerchoiceprocessofdoublethedoubledegreeprogram.Inmyopinion,thecollegestudentstreatthedoubledegreeprogramasaPositive,higherexpectedreturnstrategy.NotaffectingthemainIImajor,thestudentscangainmoreabilities,achievemorecareerinformation,andhelptoexplorevocationalinterestandimprovecareercognition.KeyWords:careercircumscriptionandcompromise;doubledegreehttps://max.book118.com/html/2018/0729/6142230132001210.shtm
6.輔系/雙主修規定Minor/DoubleMajorRegulations申請時程 Application Time 比照學校規定辦理 雙主修規定 Double Major Regulations 申請時程與資格依照學校規定。 訂定最低學分數門檻:修讀本系學士班雙主修學生,應修習院定+系定所有必修科目,且其畢業學分數在扣除與主修學系重複的必修科目後,仍至少需修習40學分以上。https://qf.site.nthu.edu.tw/p/412-1366-5856.php
7.ACTIVEMAJORDOUBLEO酷狗音乐AI·DJ AI唢呐 AI钢琴 AI骨笛 AI伴奏 AI清唱 AI尤克 AI调速 下载歌曲打开酷狗 评论歌手 精彩评论 还没有人发评论,快来抢沙发吧! 歌手 MAJORDOUBLEO 0粉丝关注 打开酷狗收听更多精彩ACTIVE 正在收听 打开酷狗音乐,尽享丰富听歌体验 蝰蛇音效 千万曲库 超清MV 打开酷狗收听https://m3ws.kugou.com/kgmixsong/74fhlk08.html
8.6大设计原则精通设计模式之里氏代换原则:从理论到实践,掌握代码演{privatedoublewidth;privatedoubleheight;publicRectangle(doublewidth,doubleheight){this.width=width;this.height=height;}@OverridepublicdoublegetArea(){returnwidth*height;}}// 新增的椭圆类publicclassEllipseextendsAbstractShape{privatedoublemajorRadius;privatedoubleminorRadius;publicEllipse(doublemajorRadius,doublehttps://blog.csdn.net/qq_27362017/article/details/141224173
9.doublemajor是什么意思doublemajor中文意思I'm now working on a double major. 我目前在攻读双学位. 互联网 2、 As an undergraduate, I had a double major of Chinese and Mass Communication. 本人在读大学本科时, 曾主修中文和大众传播学. 互联网 3、 She graduated from Beijing university with a double-major in Economics and Environmenthttps://dict.ruihongw.com/double%20major
10.N乙酰半胱氨酸的功效与作用有效性与不利性N-乙酰半胱氨酸(NAC)是L-半胱氨酸的前药(前体药物),其用于在通常耗尽时能够产生更多谷胱甘肽。通过谷胱甘肽缓冲,NAC提供抗氧化作用和其他好处。 在人类中,已经注意到血清铅的减少。 N-乙酰半胱氨酸可具有直接的矿物螯合作用。铅是一种重金属矿物,被称为继发于灭活谷胱甘肽的有毒物质,铅的毒性作用很大程度上受到细https://www.foodwake.com/supplement/210
11.亲睦家告诉您梨的功效.成都养老院成都养老机构成都旅居养老亲 Pushing back "Good Dinosaur" to 2015 removes a major film from the media company's movie slate next year, Wedge Partners analyst Martin Pyykkonen said. The postponement of both movies likely contributed to a decline in Disney shares, he said. 匿名用户http://www.qinmujia.com/%E6%88%90%E9%83%BD%E4%BA%B2%E7%9D%A6%E5%AE%B6%E6%A2%A8-%E5%8F%AF%E6%98%AF%E4%B8%AA%E5%A4%A7%E5%AE%9D%E8%B4%9D%E9%99%A4%E5%BC%80%E6%B6%A6%E8%82%BA%E6%AD%A2%E5%92%B3%E8%BF%98%E6%9C%89%E6%9B%B4%E5%A4%A7%E7%9A%84%E5%8A%9F%E6%95%88
12.XDDFDateAxis(POIAPIDocumentation)public void setMajorUnit(double major) Specified by: setMajorUnit in class XDDFChartAxis (类 XDDFChartAxis 中的 setMajorUnit) Parameters: major - axis major unit (主轴主要单位) getMajorUnit public double getMajorUnit() Specified by: getMajorUnit in class XDDFChartAxis (类 XDDFChartAxis 中http://51helpdoc.com/doc/poi/5.0.0/apidocs/org/apache/poi/xddf/usermodel/chart/XDDFDateAxis.html
13.THEORIGINOFDOUBLEThe ionized gas emission is spatially coincident with the galaxy's major axis (Fig. 4), suggesting that the source of the double-peaked narrow emission lines is in the plane of the galaxy (PA[OIII]~PAgal). Recent HST observations of this galaxy support this interpretation. As can be http://arxiv.org/pdf/1509.04291
14.approximatelydoubletheheartrateandkeepitdoubledaAs the popularity of exercise continues to mount, so does scientific evidence of its health benefits. The key to fitness is exercising the major muscle groups vigorously (强有力地) enough to approximately double the heart rate and keep it doubled for 20 to 30 minutes at a time. Doing suchhttp://eyu.zaixian-fanyi.com/fan_yi_6775846
15.新能源汽车好处英语作文合集汽车的好处与坏处--英语作文.实用文档.With the rapid development of science and technology, the car has turned from a luxury into into the millions of products. Just as the saying goes: everything has two sides, while the car's appearance is a double-edged sword: an irreplaceable advantage https://wenku.baidu.com/aggs/6fe40e2a915f804d2b16c12c.html
16.网络的利与弊英语作文(通用34篇)随着高科技的发展,互联网越来越普及。无论孩子还是老人都知道如何上网搜索。互联网的出现给人们带来了很多好处,但人们也普遍发现它给他们带来了伤害。 首先,互联网给人们带来了很多便利和丰富多彩的世界。有了互联网,人们可以购买家里所有的东西,搜索各种信息,与来自世界各地的人交朋友等等。没有互联网,人们就无法享受https://m.ruiwen.com/zuowen/wangluo/2602894.html
17.高性能mysql第四版epub高性能mysql第五版pdf百度云高性能mysql第四版 epub 高性能mysql第五版 pdf百度云,目录第一章数据库概述1.1、数据库的好处1.2、数据库的常见概念1.3、数据库的存储特点1.4、数据库的常见分类1.5、SQL语言的分类第二章MySQL概述2.1、MySQL的背景2.2、MySQL的优点2.3、MySQL的安装2.4、MySQL的启动2.5、https://blog.51cto.com/u_16099276/9320648
18.面经分享:美团面试也太难了!4面美团终成Offer这里我就主要讲了Synchronized关键字,还有并发包下面的一些锁,以及各自的优缺点和区别。volatile关键字我主要从可见性、原子性和禁止JVM指令重排序三个方面讲的,再讲了一下我在多线程的单例模式double-check中用到volatile关键字禁止JVM指令重排优化。 3、集合:HashMap底层实现,怎么实现HashMap线程安全 https://maimai.cn/article/detail?fid=1651880698&efid=Gn-Vh8Nj4BB_v7sWtHb2mQ
19.优先匹配再增门槛受信账户现已重磅上线5EPlay如何升级成为受信账户,受信认证后的好处? 仅需以下两步即可升级成为受信账户: 受信账户评分系统将从:5E平台天梯时长、5E信用分、5E社区行为、CS:GO生涯数据、Steam账号价值等多个账号数据维度对账号进行全方位考察,限制高风险账号进入5E优先匹配环境。评分通过后,需完成扫脸并绑定5E令牌方可登陆客户端(注意:人脸ID一https://csgo.5eplay.com/article/trusted-national-priority-age-831-blockbuster-online-account
20.乔治华盛顿大学就读体验分享:校园环境/教学条件/食宿生活介绍在GW转专业与double major都是比较容易。你需要先在学校网站上查询要求,然后去选所需要的课,最后拿着成绩去和advisor谈计划,一般他们都会批准的。 写在最后 希望以上内容的分享,可以帮助喜欢乔治华盛顿大学的小可爱们,更好地了解其校园环境、生活以及学习经历等等。 https://www.testdaily.cn/34097/
21.英语四级作文范文(附历年作文)友谊是我们生活中不可缺少的东西。在我们漫长的人生旅途中,我们会遇到各种各样的人,结交各种各样的朋友。我们应该学习如何与朋友或同学保持良好的友谊,并体验友谊给我们带来的好处。 在日常生活中,当我们的朋友或同学遇到困难时,我们可以表现出乐于助人的良好品格,当他们感到沮丧时,我们可以安慰他们。这有利于保持双方https://www.oh100.com/kaoshi/cet4/zuowen/476289.html
22.C++课程设计(简单图书管理系统)6篇(全文)} Student *p=new Student;cout<<“学生名字:”;cin>>(*p).name;cout<<“学生年龄:”;cin>>(*p).age;cout<<“学生性别:”;cin>>(*p).sex;cout<<“学生学号:”;cin>>(*p).number;cout<<“学生专业:”;cin>>(*p).major;head.Add(p);//在链表末尾增加一个节点 https://www.99xueshu.com/w/fileiuknvdrv.html