纠纷奇闻作文社交美文家庭
聚热点
家庭城市
爱好生活
创业男女
能力餐饮
美文职业
心理周易
母婴奇趣
两性技能
社交传统
新闻范文
工作个人
思考社会
作文职场
家居中考
兴趣安全
解密魅力
奇闻笑话
写作笔记
阅读企业
饮食时事
纠纷案例
初中历史
说说童话
乐趣治疗

java浅谈java内部类

5月25日 先锋客投稿
  前言
  说到java内部类,想必大家首先会想到比较常用的匿名内部类,但实际上,这只是内部类的其中一种使用方式而已。内部类的使用方式实际上总共包括:成员内部类,方法局部类,匿名内部类,下面,我就给大家来一一介绍:为什么要使用内部类
  有的时候你可能有这样一种需求:对一个类(假设它为MyClass。java)创建一个和它相关的类(假设它是Part。java),但因为Part。java和MyClass之间的联系紧密且单一,导致我们在这种情况下,不希望像下面这样增加一个额外的兄弟类MyClassPart
  复制
  而希望能将Part。java的数据隐藏在MyClass。java内部,于是这个时候内部类就堂而皇之地出现了
  那么,这个不请自来的内部类到底给我们上述的局面造成了怎样的改变呢?让我们来看看:
  增加一个额外的兄弟类Part:
  1。对一些没有关联的类可见(如果protected则对同一包内类可见,如果public则对所有类可见)
  2。不能完全自由的访问MyClass中的私有数据(必须经过访问器方法)
  3。新增了一个java文件
  使用内部类,将Part类的定义写入MyClass内部
  1。可以减少多余的可见性,例如可把Part在MyClass内部定义为私有,这样对同一包内其他类也不可见了
  2。内部类(Part)可以自由访问外围类的所有数据(MyClass),包括私有数据
  3。减少了一个java文件,使得类结构更简洁成员内部类
  故名思议,成员内部类嘛使用当然和成员变量很相似咯
  你可以像privateStringdata
  复制
  这样定义一个平行的成员内部类:privateclassInner
  复制
  具体看下面的例子:
  Outter。java:publicclassOutter{成员变量dataprivateStringdata外部数据;定义一个内部类privateclassInner{publicvoidinnerPrint(){System。out。println(data);}}外部类的方法,new一个内部类的实例并调用其innerPrint方法publicvoidoutterPrint(){InnerinewInner();i。innerPrint();}}
  复制
  Test。java:publicclassTest{publicstaticvoidmain(String〔〕args){OutteronewOutter();o。outterPrint();}}
  复制
  结果输出:外部数据
  复制
  看来这还是能达到我们预期的效果的:由于将Inner内部类设为private,它变得只对我们当前的外部类Outter类可见,我们成功地把它隐藏在了Outter类内部,与此同时,它还自由地访问到了Outter类的私有成员变量data两个this
  虽然上面的例子看起来挺简单的,但实际上内部类的作用机制还是比较复杂的。
  首先要考虑的是this的问题,外部类和内部类各有一个this,关键在于内部类中我们如何对这两个this作出区分:
  我们假设上面的例子中的Inner类内部有一个方法fn:privateclassInner{publicvoidfn(){Outter。this指向Outter实例对象的this引用this指向Inner实例对象的this引用}}
  复制
  在这个方法fn里,Outter。this是指向Outter实例对象的this的引用,而this是指向Inner实例对象的this的引用
  我们访问类中成员变量有两种方式:隐式访问(不加this)和显式访问(加this)隐式访问类中成员变量
  让我们对上面的Outter。java做一些改动,增加一行代码:publicclassOutter{成员变量dataprivateStringdata外部数据;定义一个内部类privateclassInner{增加Inner类对data成员变量的声明privateStringdata内部数据publicvoidinnerPrint(){System。out。println(data);}}外部类的方法,new一个内部类的实例并调用其innerPrint方法publicvoidoutterPrint(){InnerinewInner();i。innerPrint();}}
  复制
  结果输出:内部数据
  复制
  如此可见,内部类内声明的数据会覆盖外部类的同名数据。或者说,在上述例子中,对于data成员变量,它会首先在Inner的this中查找有无这个成员变量,然后没有,那么就再在Outter。this中查找显式访问类中成员变量
  但有的时候我们希望既能访问外部类的成员变量,同时也能访问内部类的成员变量,这个时候我们就要使用到this了,但是如何区分内部类和外部类的this呢?你可以这样:
  以上述例子为例:
  访问外部类定义的成员变量:Outter。this。data
  访问内部类定义的成员变量:this。data
  如下图所示publicclassOutter{外部类的成员变量dataprivateStringdata外部数据;定义一个内部类privateclassInner{内部类的成员变量dataprivateStringdata内部数据;publicvoidinnerPrint(){System。out。println(Outter。this。data);System。out。println(this。data);}}外部类的方法,new一个内部类的实例并调用其innerPrint方法publicvoidoutterPrint(){InnerinewInner();i。innerPrint();}}
  复制局部内部类
  局部内部类是内部类的第二种形式,它让内部类的隐藏得更深一层写在外部类的方法内部,而不是处于和外部类方法平行的位置。
  让我们对上面成员内部类处理的场景做些思考:我们的Inner内部类仅仅只在outterPrint方法中使用了一次:publicvoidoutterPrint(){InnerinewInner();i。innerPrint();}
  复制
  那么我们能不能把Inner内部类直接定义在outterPrint的内部呢?这样的话,它就能更好地隐藏起来,即使是类Outter中除outterPrint外的方法,也不能访问到它:
  现在的Outter的类看起来像这样:publicclassOutter{publicvoidoutterPrint(){外部类方法classLocalInner{局部内部类publicvoidinnerPrint(){}}LocalInnerinewLocalInner();实例化局部内部类i。innerPrint();}}
  复制
  相比于成员内部类,局部内部类多了一项能访问的数据,那就是局部变量(由外部类方法提供)
  成员内部类:外部类数据,内部类数据
  局部内部类:外部类数据,内部类数据,局部数据
  具体示例如下:
  Outter。javapublicclassOutter{privateStringdata外部数据;外部类数据publicvoidoutterPrint(finalStringlocalData){局部数据classLocalInner{privateStringdata内部数据;内部类数据publicvoidinnerPrint(){System。out。println(Outter。this。data);打印外部类数据System。out。println(this。data);打印内部类数据System。out。println(localData);打印局部数据}}LocalInnerinewLocalInner();i。innerPrint();}}
  复制
  Test。java:publicclassTest{publicstaticvoidmain(String〔〕args){OutteronewOutter();o。outterPrint(局部数据);}}
  复制
  结果输出:外部数据内部数据局部数据
  复制局部类所使用的外部类方法的形参必须用final修饰
  这里要注意一点,局部类所使用的外部类方法的形参必须用final修饰,否则会编译不通过,也就是说传入后不许改变为什么这个方法形参一定要用final修饰?
  (仅个人理解,如有不同的意见或者更好的理解欢迎在评论区讨论)
  如果不用final修饰会怎样?且听我慢慢道来:
  首先要说一下:
  1。内部类和外部类在编译之后形式上是一样的,不会有内外之分
  2。局部内部类对于使用的外部方法的值会用构造函数做一个拷贝(编译后)
  例如对于下面outterPrint方法中的LocalInnerpublicvoidoutterPrint(finalStringdata){classLocalInner{publicvoidinnerPrint(){使用data}}}
  复制
  编译之后大概长这样:publicclassOutterLocalInner{publicLocalInner(Stringdata){this。LocalI对于使用的data做了一次拷贝}publicvoidinnerPrint(){使用data}}
  复制
  这里要注意的是:
  1。编译后,LocalInner并非直接使用data,而是用构造器拷贝一份后再使用
  2。java是值传递的,所以包裹LocalInner的外部方法outterPrint也会对传入的data参数做一次拷贝(基本类型数据拷贝副本,对象等则拷贝引用)
  ,现在的情况是:
  方法内的局部类对data拷贝了两次:外部方法outterPrint值传递时的拷贝,和LocalInner构造函数的拷贝
  方法内除了局部类外的作用域只拷贝了data一次:外部方法outterPrint值传递时的拷贝
  拷贝两次和拷贝一次,导致在outterPrint方法内部,局部类内部的data和局部类外部的data是不同步的!也即你在局部类内部改了data不影响局部类外部的data,在局部类外部改了data也不影响局部类内部的data(注意一个前提,值是基本类型的,如果是对象的话因为拷贝的是引用仍然可以同步)
  图示一:
  图示二:
  于是java说:哎呀妈呀,这都data都不同步了,要是让你修改这还了得!!!于是就强行要求我们加上final
  【注意】所谓的不同步主要是针对基本类型来说的,如果是对象之类的话因为拷贝的是引用所以仍然可以同步如何突破必须用final的限制
  我们上面说到,局部内部类所使用的方法形参必须用final修饰的限制。
  例如publicvoidoutterPrint(Stringdata){没加上finalclassLocalInner{publicvoidchangeData(){data我想修改data的值;在这一行编译报错}}}
  复制
  提示:Cannotrefertoanonfinalvariabledatainsideaninnerclassdefinedinadifferentmethod
  复制
  那么,如果我们有对该形参必须能修改的硬性需求怎么办?
  你可以通过一种有趣的方式绕开它:使用一个单元素数组。因为用final修饰的基本类型的变量不允许修改值,但是却允许修改final修饰的单元素数组里的数组元素,因为存放数组的变量的值只是一个引用,我们修改数组元素的时候是不会修改引用指向的地址的,在这点上final并不会妨碍我们:
  Outter。javapublicclassOutter{publicvoidoutterPrint(finalString〔〕data){classLocalInner{publicvoidinnerPrint(){data〔0〕堂而皇之地修改它!!;修改数据System。out。print(data〔0〕);输出修改后的数据}}LocalInnerinewLocalInner();i。innerPrint();}}
  复制
  Test。java:publicclassTest{publicstaticvoidmain(String〔〕args){OutteronewOutter();String〔〕datanewString〔1〕;data〔0〕我是数据;o。outterPrint(data);修改数据并且输出}}
  复制
  结果输出:堂而皇之地修改它!!
  复制
  【注意】局部类不能用public或private访问符进行声明!!匿名内部类
  倘若我们再把局部内部类再深化一下,那就是匿名内部类匿名内部类的使用方式new〔超类接口〕{类体}
  复制
  让我们看看下面这个例子:
  Other。java:publicclassOther{}
  复制
  Outter。java:publicclassOutter{publicvoidoutterPrint(Stringdata){OtheronewOther(){};匿名内部类}}
  复制何谓之匿名?
  诶,不是说好的匿名吗?那么为什么还有个Other的类名呢?OtheronewOther(){匿名内部类的类体};
  复制
  实际上,这里的Other并不是我们的匿名内部类,而是我们匿名内部类的超类,上面一行代码其实相当于(用成员内部类来表示的话)annoymous翻译为匿名publicclassOutter{privateclassannoymousextendsOther{}publicvoidoutterPrint(){Otheranewannoymous();}}
  复制
  同时要注意,我们在使用匿名内部类的方式,是在定义一个内部类的同时实例化该内部类:newOther(){匿名内部类的类体};new操作和定义类的代码是紧紧结合在一起的
  复制匿名函数的作用
  用匿名函数的作用在于在一些特定的场景下写起来很简单,例如事件监听器:ActionListenerlistenernewActionListener(){publicvoidactionPerformed(ActionEvente){}};
  复制
  避免了再创建另外一个类文件
  讲的有点乱,对匿名内部类做个总结:
  1。省略被定义的类的类名
  2。必须结合超类或者接口使用,即new〔超类接口〕{类体}
  3。在定义该匿名类的同时实例化该匿名类
  4。在一些场景下能简化代码
  【注意】匿名类不能有构造器,因为构造器和类同名,而匿名类没有类名,所以匿名类不能有构造器文章总结
  我们使用内部类的原因主要有三点:
  1。实现数据隐藏,避免多余的可见性
  2。自由访问外部类的变量
  3。在使用监听器等场景的时候使用匿名内部类,避免增加的大量代码
  关于成员内部类,方法局部类,匿名内部类的关系
  从成员内部类,方法局部类到匿名内部类是一个不断深入的关系,成员内部类进一步隐藏可见性就成为了方法局部类,方法局部类省去类名,并将类的定义和实例化操作合并到一起,就是匿名内部类。因此,匿名内部类沿袭了成员内部类和方法局部类的基本特特性
  内部类的一些特殊的要求
  1。局部类不能用public或private访问符进行声明
  2。局部类所使用的外部类方法的形参必须用final修饰
  3。匿名内部类不能有构造器
  参考资料:
  《java核心技术卷1》CayS。Horstmann,GaryCornell
投诉 评论 转载

java浅谈java内部类前言说到java内部类,想必大家首先会想到比较常用的匿名内部类,但实际上,这只是内部类的其中一种使用方式而已。内部类的使用方式实际上总共包括:成员内部类,方法局部类,匿名……体坛浙江队高层此前并未抵达苏州,而是忙于筹备球队25周年庆典直播吧1月12日讯在昨天的足协杯半决赛中,浙江队通过点球大战53淘汰海港队晋级决赛。据《体坛周报》消息,浙江队高层正忙于准备25周年庆等相关事宜,因此并未抵达杭州督战。在……如何度过炎炎夏季呢?小编分享啦随着全球气候日益变暖,夏季全国大部分地区都酷暑难耐。而在这么炎热的天气,仍要继续放化疗的乳腺癌病友,消化功能减低,胃口自然更差,加上放化疗的副作用,如恶心呕吐、骨髓抑制、内分泌……日本知名实业家稻盛和夫去世,曾创办两家世界500强,78岁出每经编辑:王月龙,盖源源据海外网援引日媒报道,日本知名实业家、京瓷名誉会长稻盛和夫去世,终年90岁。稻盛和夫在27岁时创立了京瓷,又在52岁创立第二电信KDDI,这……四川凉山,有多少极致风光?摄:邹森凉辰美景,山藏古今在四川和云南交界之处有一方隐匿世外的蓬莱仙境四川凉山提及凉山二字大多数人仍觉得陌生而遥远仿若地球的另一端……大美新疆,喀纳斯告诉你什么是真正的人间仙境因工作原因,有幸在新疆待了几年,在没有疫情影响时,或跟团旅游,或开车自驾,亲眼看到了新疆宛如仙境的美景。在那样的地方,也难怪能养育出如佟丽娅、迪丽热巴等这样美丽的人。今日……人不是慢慢变老的,人是瞬间变老的你用一句话证明自己老了人不是慢慢变老的,人是瞬间变老的。村上春树。明明以前加班到12点,还可以K歌撸串,玩到后半夜,但现在只要一到后半夜,眼睛就开始睁不开。以前喝一……老动物园的门票作者:静华语嫣老哈尔滨人,哪个不回忆老动物园?那里可是咱们的童年啊!还记得熊山、还有猴山、孔雀笼还有高空脚踏车,碰碰车、旋转木马、和疯狂老鼠。这些小时候特别喜……从一场球赛到一口甘甜,百岁山长期主义背后的民族情和民生味文丨快消君昨晚,2022年世界杯男排联赛巴西利亚站展开第6比赛日的争夺。与卫冕冠军巴西队交手,中国男排敢打敢拼表现超预期,直落三局完胜劲敌,斩获今年国家联赛的首胜。主攻张……幸福!德约科维奇夺冠后与一对儿女拥抱亲吻庆祝,有爱互动萌出天北京时间11月8日,在夺得2021年巴黎网球大师赛冠军后,塞尔维亚天王德约科维奇第一时间跑到场边,与一对儿女拥抱、亲吻、击掌。看到爸爸赢得最后的胜利,德维科维奇的一对儿女……华为又流失一位高管,曾是华为智能车控总经理,现已加入宁德时代4月29日,雷峰网消息,据36氪从知情人士处获悉,华为智能汽车解决方案BU智能车控领域总经理蔡建永已从华为离职,并加入了电池企业公司宁德时代,任宁德时代CTC电池底盘一体化业务……2022年最成功的三款机型,配置出色不说,关键价格还公道如果你问我今年哪款手机最值得购买,那我一定会回答这三款机型,配置表现出色,性价比还高,入手真的很不错。第一款:华为P50Pro处理器:骁龙888麒麟9000屏幕:6……
女排开启大调整朱婷伤停到4月,郎平迎接新职位,蔡斌成了赢家筑梦新材职等你来系列校招活动走进湘潭大学再小的个体也应该要有自己的数字管理系统00,爆大冷!欧冠7冠王倒下,62控球仍翻车,11射0球,争10位九零后男星的时尚业绩易烊千玺大满贯,王一博排倒数第一丁克就可以忽略避孕?错!丁克才更需要避孕!发生了什么?雷军退出多家小米关联公司中国半永久纹绣技术名师,本色纹绣培训学校高级讲师胡真女士孟姜女是个葫芦娃?长清齐长城下长城村的传奇湖人正式报价罗齐尔!布里奇斯也在招募中快手内急传奇M国际服公测服提示无法登录,服务器出现意料外错误解决教程
与君初相识上线郭晓婷顺德仙姬花路出场氛围感拉满老人协会给时间的抗议书为什么鼻子周围总是能挤出白色物体?怎样才能彻底清除干净?健康养生:怎么调脾胃冬季进补养阴温肾壮阳作文学会包容600字藏在鹤山玥湖又一湖畔园林酒店开业,畅游超大泳池,海鲜吃到扶墙高二英语教学反思范文三篇我们是奇瑞粉丝团为瑞虎8鲲鹏版点赞鸡你太美(鸡你太美到底是什么意思?)热传聚热点网 小米水浸卫士日上架元开售支持小时智能监测孩子几岁和父母分床睡合适我想留住这片风景

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找美丽时装彩妆资讯历史明星乐活安卓数码常识驾车健康苹果问答网络发型电视车载室内电影游戏科学音乐整形