




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Java:失效的private修饰符本文主要介绍Java 失效的private修饰符,这里整理了相关资料说明private 修饰符的作用,如何使用并与C+ 做比较,有兴趣的小伙伴可以参考下在Java编程中,使用private关键字修饰了某个成员,只有这个成员所在的类和这个类的方法可以使用,其他的类都无法访问到这个private成员。上面描述了private修饰符的基本职能,今天来研究一下private功能失效的情况。Java内部类在Java中相信很多人都用过内部类,Java允许在一个类里面定义另一个类,类里面的类就是内部类,也叫做嵌套类。一个简单的内部类实现可以如下?1234class Out
2、erClass class InnerClass今天的问题和Java内部类相关,只涉及到部分和本文研究相关的内部类知识,具体关于Java内部类后续的文章会介绍。第一次失效?一个我们在编程中经常用到的场景,就是在一个内部类里面访问外部类的private成员变量或者方法,这是可以的。如下面的代码实现。?123456789101112131415161718public class OuterClass private String language = en;private String region = US;public class InnerClass public void printOu
3、terClassPrivateFields() String fields = language= + language + ;region= + region;System.out.println(fields);public static void main(String args) OuterClass outer = new OuterClass();OuterClass.InnerClass inner = outer.new InnerClass();inner.printOuterClassPrivateFields();这是为什么呢,不是private修饰的成员只能被成员所述的
4、类才能访问么?难道private真的失效了么?编译器在捣鬼?我们使用javap命令查看一下生成的两个class文件OuterClass的反编译结果?1234567891011121314151617181920212223242526272829303132333435363738394041424344454615:30 $ javap -c OuterClassCompiled from OuterClass.javapublic class OuterClass extends java.lang.Objectpublic OuterClass();Code:0: aload_01: i
5、nvokespecial #11; /Method java/lang/Object.:()V4: aload_05: ldc #13; /String en7: putfield #15; /Field language:Ljava/lang/String;10: aload_011: ldc #17; /String US13: putfield #19; /Field region:Ljava/lang/String;16: returnpublic static void main(java.lang.String);Code:0: new #1; /class OuterClass3
6、: dup4: invokespecial #27; /Method :()V7: astore_18: new #28; /class OuterClass$InnerClass11: dup12: aload_113: dup14: invokevirtual #30; /Method java/lang/Object.getClass:()Ljava/lang/Class;17: pop18: invokespecial #34; /Method OuterClass$InnerClass.:(LOuterClass;)V21: astore_222: aload_223: invoke
7、virtual #37; /Method OuterClass$InnerClass.printOuterClassPrivateFields:()V26: returnstatic java.lang.String access$0(OuterClass);Code:0: aload_01: getfield #15; /Field language:Ljava/lang/String;4: areturnstatic java.lang.String access$1(OuterClass);Code:0: aload_01: getfield #19; /Field region:Lja
8、va/lang/String;4: areturn咦?不对,在OuterClass中我们并没有定义这两个方法?12345678910111213static java.lang.String access$0(OuterClass);Code:0: aload_01: getfield #15; /Field language:Ljava/lang/String;4: areturnstatic java.lang.String access$1(OuterClass);Code:0: aload_01: getfield #19; /Field region:Ljava/lang/Strin
9、g;4: areturn从给出来的注释来看,access$0返回outerClass的language属性;access$1返回outerClass的region属性。并且这两个方法都接受OuterClass的实例作为参数。这两个方法为什么生成呢,有什么作用呢?我们看一下内部类的反编译结果就知道了。OuterClass$InnerClass的反编译结果?1234567891011121314151617181920212223242526272829303132333435363715:37 $ javap -c OuterClass$InnerClassCompiled from Outer
10、Class.javapublic class OuterClass$InnerClass extends java.lang.Objectfinal OuterClass this$0;public OuterClass$InnerClass(OuterClass);Code:0: aload_01: aload_12: putfield #10; /Field this$0:LOuterClass;5: aload_06: invokespecial #12; /Method java/lang/Object.:()V9: returnpublic void printOuterClassP
11、rivateFields();Code:0: new #20; /class java/lang/StringBuilder3: dup4: ldc #22; /String language=6: invokespecial #24; /Method java/lang/StringBuilder.:(Ljava/lang/String;)V9: aload_010: getfield #10; /Field this$0:LOuterClass;13: invokestatic #27; /Method OuterClass.access$0:(LOuterClass;)Ljava/lan
12、g/String;16: invokevirtual #33; /Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;19: ldc #37; /String ;region=21: invokevirtual #33; /Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;24: aload_025: getfield #10; /Field this$0:LOute
13、rClass;28: invokestatic #39; /Method OuterClass.access$1:(LOuterClass;)Ljava/lang/String;31: invokevirtual #33; /Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;34: invokevirtual #42; /Method java/lang/StringBuilder.toString:()Ljava/lang/String;37: astore_138: gets
14、tatic #46; /Field java/lang/System.out:Ljava/io/PrintStream;41: aload_142: invokevirtual #52; /Method java/io/PrintStream.println:(Ljava/lang/String;)V45: return下面代码调用access$0的代码,其目的是得到OuterClass的language 私有属性。13: invokestatic #27; /Method OuterClass.access$0:(LOuterClass;)Ljava/lang/String;下面代码调用了a
15、ccess$1的代码,其目的是得到OutherClass的region 私有属性。28: invokestatic #39; /Method OuterClass.access$1:(LOuterClass;)Ljava/lang/String;注意:在内部类构造的时候,会将外部类的引用传递进来,并且作为内部类的一个属性,所以内部类会持有一个其外部类的引用。this$0就是内部类持有的外部类引用,通过构造方法传递引用并赋值。?12345678910final OuterClass this$0;public OuterClass$InnerClass(OuterClass);Code:0: a
16、load_01: aload_12: putfield #10; /Field this$0:LOuterClass;5: aload_06: invokespecial #12; /Method java/lang/Object.:()V9: return小结这部分private看上去失效可,实际上并没有失效,因为当内部类调用外部类的私有属性时,其真正的执行是调用了编译器生成的属性的静态方法(即acess$0,access$1等)来获取这些属性值。这一切都是编译器的特殊处理。这次也失效?如果说上面的写法很常用,那么这样的写法是不是很少接触,但是却可以运行。?1234567891011publ
17、ic class AnotherOuterClass public static void main(String args) InnerClass inner = new AnotherOuterClass().new InnerClass();System.out.println(InnerClass Filed = + inner.x);class InnerClass private int x = 10;和上面一样,使用javap反编译看一下。不过这次我们先看一下InnerClass的结果?12345678910111213141516171819202122232416:03 $
18、javap -c AnotherOuterClass$InnerClassCompiled from AnotherOuterClass.javaclass AnotherOuterClass$InnerClass extends java.lang.Objectfinal AnotherOuterClass this$0;AnotherOuterClass$InnerClass(AnotherOuterClass);Code:0: aload_01: aload_12: putfield #12; /Field this$0:LAnotherOuterClass;5: aload_06: i
19、nvokespecial #14; /Method java/lang/Object.:()V9: aload_010: bipush 1012: putfield #17; /Field x:I15: returnstatic int access$0(AnotherOuterClass$InnerClass);Code:0: aload_01: getfield #17; /Field x:I4: ireturn又出现了,编译器又自动生成了一个获取私有属性的后门方法access$0一次来获取x的值。AnotherOuterClass.class的反编译结果?1234567891011121
20、314151617181920212223242526272829303132333416:08 $ javap -c AnotherOuterClassCompiled from AnotherOuterClass.javapublic class AnotherOuterClass extends java.lang.Objectpublic AnotherOuterClass();Code:0: aload_01: invokespecial #8; /Method java/lang/Object.:()V4: returnpublic static void main(java.la
21、ng.String);Code:0: new #16; /class AnotherOuterClass$InnerClass3: dup4: new #1; /class AnotherOuterClass7: dup8: invokespecial #18; /Method :()V11: dup12: invokevirtual #19; /Method java/lang/Object.getClass:()Ljava/lang/Class;15: pop16: invokespecial #23; /Method AnotherOuterClass$InnerClass.:(LAno
22、therOuterClass;)V19: astore_120: getstatic #26; /Field java/lang/System.out:Ljava/io/PrintStream;23: new #32; /class java/lang/StringBuilder26: dup27: ldc #34; /String InnerClass Filed =29: invokespecial #36; /Method java/lang/StringBuilder.:(Ljava/lang/String;)V32: aload_133: invokestatic #39; /Met
23、hod AnotherOuterClass$InnerClass.access$0:(LAnotherOuterClass$InnerClass;)I36: invokevirtual #43; /Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;39: invokevirtual #47; /Method java/lang/StringBuilder.toString:()Ljava/lang/String;42: invokevirtual #51; /Method java/io/PrintStream.
24、println:(Ljava/lang/String;)V45: return其中这句调用就是外部类通过内部类的实例获取私有属性x的操作33: invokestatic #39; /Method AnotherOuterClass$IClass.access$0:(LAnotherOuterClass$InnerClass;)I再来个总结其中java官方文档 有这样一句话if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (7.6) that encloses the
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 加强林业资源保护重视林业快速发展
- 中小学生法制教育主题班会
- 跨境电商代理授权及售后服务合同
- 汽车销售公司车辆售后服务及客户关系维护合同
- 仓储式超市场地租赁合同
- 国际快递常年运输合同范本
- 商业街区立体停车库租赁及运营管理合同
- 中班健康:我的心情管理
- 阳光物业子公司下属员工选聘与岗位培训合同
- 餐厅厨房承包与特色调料研发合同
- 2022年医学专题-肝内胆管结石详解
- 涉密表格台账
- 明阳风机培训课件
- 委外加工流程
- 住院医嘱审核登记表-9月上
- Q∕SY 05010-2016 油气管道安全目视化管理规范
- 蓝海华腾变频器说明书
- 中国海洋大学论文封面模板
- 遵义会议-(演示)(课堂PPT)
- 订单(英文范本)PurchaseOrder
- 雨污水合槽沟槽回填施工专项方案(优.选)
评论
0/150
提交评论