zoukankan      html  css  js  c++  java
  • javap反编译解释外部类直接使用内部类private字段的原理

    2016-07-04 15:56:39

    我们都知道:

    1、内部类可以直接访问外部类的private字段和方法;

    2、非静态内部类持有外部类的引用;

    3、外部类可以直接访问内部类的private字段和方法(不管是不是静态内部类);

    最近看到一篇文章,大意是讨论这个的,处于好奇,想从字节码的角度研究一下原因,于是有此文。

    1、关于javap命令:

    "The javap command disassembles one or more class files. The output depends on the options used. When no options are used, then the javap command prints the package, protected and public fields, and methods of the classes passed to it. The javap command prints its output to stdout".

    来及Oracle官网的解释,大意是:javap命令用来反汇编一个或多个class文件,输出结果取决于你是用的参数。在不使用任何参数的情况下,javap命令打印出package, protected and public修饰的变量以及传给该类的方法。javap命令将输出打印到stdout。

    说白了,javap是JDK提供的一个反汇编的命令,可以将字节码文件反汇编成我们能看懂的代码。

    2、先上一段源码:

    使用到的命令:

    javap -c Test$A  //反编译内部类,这条命令中反斜杠“”必须得有,否则反编译的结果不正常

    javap -verbose Test //反编译主类Test

    3、非静态内部类A的反编译结果:

    private修饰的字段在字节码中并不是一个独立的字段,而是用access102()是为了private属性的和设计A法Test$A,传入了外部类引用作为参数,而且定义了一个外部类引用字段this$0。

    4、静态内部类B的反编译结果:

    对private字段的直接使用方式和非静态内部类是一样的,但是构造器没有传入外部类引用作为参数,同时也没有定义外部类引用this$0。

    可见,外部类可以直接访问内部类的private修饰的字段和方法其实是一种假象,毕竟如果真能这样,那么private的设计完整性如何保证呢?此外,关于非静态内部类如何持有外部类引用的原理,想必也应该清楚了。

    5、匿名内部类的反编译结果

    如图,匿名内部类实现了接口Inter,编译器给匿名内部类添加了构造器,同时传入了外部类的引用。

    所以,匿名内部类也是默认持有外部类的引用的。

  • 相关阅读:
    真机分享文件到虚拟机的centos 7 分享文件位置记录
    Linux系统列出某个用户组里的所有用户命令
    笔记之Linux命令vi
    笔记之Linux系统文件管理命令
    我的C#
    消息框
    ddt数据驱动在ui自动化中的应用二【多测师】
    ddt数据驱动在ui自动化中的应用一【多测师】
    基于ddt+unittest+Excel做接口测试自动化测试【多测师】
    Python操作MD5加密【多测师】
  • 原文地址:https://www.cnblogs.com/wlrhnh/p/5640543.html
Copyright © 2011-2022 走看看