JVM-Class

作者: SMSM | 来源:发表于2017-12-17 15:57 被阅读8次
    ClassFile {
           u4 magic;
           u2 minor_version;
           u2 major_version;
           u2 constant_pool_count;
           cp_info constant_pool[constant_pool_count-1];
           u2 access_flags;
           u2 this_class;
           u2 super_class;
           u2 interfaces_count;
           u2 interfaces[interfaces_count];
           u2 fields_count;
           field_info fields[fields_count];
           u2 methods_count;
          method_info methods[methods_count];
           u2 attributes_count;
           attribute_info attributes[attributes_count];
    }
    链接:https://juejin.im/post/589834a20ce4630056097a56
    每个字段含义http://blog.csdn.net/u012422829/article/details/46633515
    常量池https://www.cnblogs.com/lcchuguo/p/4470835.html
    https://github.com/HalfStackDeveloper/ClassReader/blob/master/src/com/wangxiandeng/classreader/basicinfo/MemberInfo.java
    
        //From javassist.bytecode.ClassFile
        private void read(DataInputStream in) throws IOException {
            int i, n;
            int magic = in.readInt();
            if (magic != 0xCAFEBABE)
                throw new IOException("bad magic number: " + Integer.toHexString(magic));
    
            minor = in.readUnsignedShort();
            major = in.readUnsignedShort();
            constPool = new ConstPool(in);
            accessFlags = in.readUnsignedShort();
            thisClass = in.readUnsignedShort();
            constPool.setThisClassInfo(thisClass);
            superClass = in.readUnsignedShort();
            n = in.readUnsignedShort();
            if (n == 0)
                interfaces = null;
            else {
                interfaces = new int[n];
                for (i = 0; i < n; ++i)
                    interfaces[i] = in.readUnsignedShort();
            }
    
            ConstPool cp = constPool;
            n = in.readUnsignedShort();
            fields = new ArrayList();
            for (i = 0; i < n; ++i)
                addField2(new FieldInfo(cp, in));
    
            n = in.readUnsignedShort();
            methods = new ArrayList();
            for (i = 0; i < n; ++i)
                addMethod2(new MethodInfo(cp, in));
    
            attributes = new ArrayList();
            n = in.readUnsignedShort();
            for (i = 0; i < n; ++i)
                addAttribute(AttributeInfo.read(cp, in));
    
            thisclassname = constPool.getClassInfo(thisClass);
        }
    

    Class文件的解析过程,简版如上,完全是根据ClassFile.java定义的数据格式解析的。常量池存放了当前类的所有字符信息,真的是全部的字符信息,比如String字符串、方法名、方法格式、属性名、属性类型、方法体内依赖的类。常量池的作用是合并重复项减少文件大小。也是个序列化与反序列化的过程,如下所示:

       ------FragmentTransaction ft; 属性-------
    18 Field #45, name&type #104
    104 NameAndType #52, type #53
    52 UTF8 "ft"
    53 UTF8 "Landroid/support/v4/app/FragmentTransaction;"
    45 Class #134
    134 UTF8 "com/mrzhang/component/MainActivity"
    
    
    MainActivity ft FragmentTransaction 参数类型因为有内部类,所以要指定是当前属性属于哪个类
    
    ------ft.remove(fragment).commit(); 方法--------
    方法(常量池中某条的类型)——所属类——方法入参类型和返回类型
    19 Method #105, name&type #106
    20 Method #105, name&type #107
    
    106 NameAndType #152, type #153
    107 NameAndType #154, type #155
    
    152 UTF8 "remove"
    153 UTF8 "(Landroid/support/v4/app/Fragment;)Landroid/support/v4/app/FragmentTransaction;"
    154 UTF8 "commit"
    155 UTF8 "()I"
    
    105 Class #151
    151 UTF8 "android/support/v4/app/FragmentTransaction"
    
    
    
    
    案例1:
    .method protected onResume()V
        .locals 2
    
        .prologue
        .line 52
        invoke-super {p0}, Lcom/meituan/sankuai/erpboss/modules/BaseStatisticsActivity;->onResume()V
    
        .line 53
        invoke-static {}, Ljava/lang/System;->currentTimeMillis()J
    
        move-result-wide v0
    
        iput-wide v0, p0, Lcom/meituan/sankuai/erpboss/modules/cashier/CashierReportActivity;->mStartTime:J
    
        .line 54
        return-void
    .end method
    
    案例2:
    .method private static get$Lambda(Lcom/meituan/sankuai/erpboss/component/PickerDataManager;Landroid/content/Context;)Lrx/functions/Action1;
        .locals 1
    
        new-instance v0, Lcom/meituan/sankuai/erpboss/component/PickerDataManager$$Lambda$3;
    
        invoke-direct {v0, p0, p1}, Lcom/meituan/sankuai/erpboss/component/PickerDataManager$$Lambda$3;-><init>(Lcom/meituan/sankuai/erpboss/component/PickerDataManager;Landroid/content/Context;)V
    
        return-object v0
    .end method
    
    

    常量池中常量有多种类型Integer、Class、Method、Field、Interface、UTF8、String等。每种类型解析不一样。比如:
    2 Method #46, name&type #87
    3 Class #89
    4 Integer 2130968603

    在做类依赖关系管理时,可以扫描Class文件的常量区中的UTF8相关的类全都提取出来,就是当前类的直接依赖汇总,再基于直接类递归分析间接依赖类。

    32 Class #121
    121 UTF8 "com/mrzhang/component/MainActivity$MyAsyncTask"
    
    100 UTF8 "com/mrzhang/component/MainActivity$1"
    71 UTF8 "Lcom/mrzhang/componentservice/readerbook/ReadBookService;"
    155 UTF8 "(Landroid/support/v4/app/Fragment;)Landroid/support/v4/app/FragmentTransaction;"
    160 UTF8 "java/lang/Class"
    178 UTF8 "(Ljava/util/concurrent/Executor;[Ljava/lang/Object;)Landroid/os/AsyncTask;"
    175 UTF8 "(I)Ljava/lang/StringBuilder;"
    
    public abstract FragmentTransaction add(@IdRes int containerViewId, Fragment fragment);
    118 NameAndType #167, type #168
    167 UTF8 "add"
    168 UTF8 "(ILandroid/support/v4/app/Fragment;)Landroid/support/v4/app/FragmentTransaction;"
    

    观察特征,提取直接依赖的Class文件:
    是否包含『/』 ----> 根据";"做分割并去除空格 ----> 去除头部的"(" 或")"或 "L等大写的字符",去除尾部的";" ----> 得到类文件

    
    1 Method #9, name&type #20
    2 Method #9, name&type #21
    3 String #22
    4 String #23
    5 Method #24, name&type #25
    6 String #26
    7 String #27
    8 Class #28
    9 Class #29
    10 UTF8 "<init>"
    11 UTF8 "()V"
    12 UTF8 "Code"
    13 UTF8 "LineNumberTable"
    14 UTF8 "LocalVariableTable"
    15 UTF8 "this"
    16 UTF8 "Lcom/mrzhang/component/application/AppApplication;"
    17 UTF8 "onCreate"
    18 UTF8 "SourceFile"
    19 UTF8 "AppApplication.java"
    20 NameAndType #10, type #11
    21 NameAndType #17, type #11
    22 UTF8 "smarking"
    23 UTF8 "begin inject "
    24 Class #30
    25 NameAndType #31, type #32
    26 UTF8 "test getReadBookFragment "
    27 UTF8 "test getReadBookFragment  MainActivity"
    28 UTF8 "com/mrzhang/component/application/AppApplication"
    29 UTF8 "android/app/Application"
    30 UTF8 "android/util/Log"
    31 UTF8 "d"
    32 UTF8 "(Ljava/lang/String;Ljava/lang/String;)I"
    ClassInfo{constPool=null, thisClass=8, accessFlags=33, superClass=9, interfaces=null, thisClassName='com.mrzhang.component.application.AppApplication', major=51, minor=0}
    ClassDog find target in /Users/Smarking/AndroidStudioProjects/newworld/DDComponentForAndroid/app/build/intermediates/classes/debug/com/mrzhang/component/application/AppApplication.class
    
    1 Field #5, name&type #27
    2 Method #6, name&type #28
    3 String #29
    4 Method #30, name&type #31
    5 Class #32
    6 Class #33
    7 Class #35
    8 UTF8 "this$0"
    9 UTF8 "Lcom/mrzhang/component/MainActivity;"
    10 UTF8 "<init>"
    11 UTF8 "(Lcom/mrzhang/component/MainActivity;)V"
    12 UTF8 "Code"
    13 UTF8 "LineNumberTable"
    14 UTF8 "LocalVariableTable"
    15 UTF8 "this"
    16 UTF8 "InnerClasses"
    17 UTF8 "Lcom/mrzhang/component/MainActivity$1;"
    18 UTF8 "onClick"
    19 UTF8 "(Landroid/view/View;)V"
    20 UTF8 "v"
    21 UTF8 "Landroid/view/View;"
    22 UTF8 "SourceFile"
    23 UTF8 "MainActivity.java"
    24 UTF8 "EnclosingMethod"
    25 Class #37
    26 NameAndType #38, type #39
    27 NameAndType #8, type #9
    28 NameAndType #10, type #40
    29 UTF8 "com.mrzhang.share.applike.ShareApplike"
    30 Class #41
    31 NameAndType #42, type #43
    32 UTF8 "com/mrzhang/component/MainActivity$1"
    33 UTF8 "java/lang/Object"
    34 Class #44
    35 UTF8 "android/view/View$OnClickListener"
    36 UTF8 "OnClickListener"
    37 UTF8 "com/mrzhang/component/MainActivity"
    38 UTF8 "onCreate"
    39 UTF8 "(Landroid/os/Bundle;)V"
    40 UTF8 "()V"
    41 UTF8 "com/mrzhang/component/componentlib/router/Router"
    42 UTF8 "unregisterComponent"
    43 UTF8 "(Ljava/lang/String;)V"
    44 UTF8 "android/view/View"
    ClassInfo{constPool=null, thisClass=5, accessFlags=32, superClass=6, interfaces=[7], thisClassName='com.mrzhang.component.MainActivity$1', major=51, minor=0}
    ClassDog find target in /Users/Smarking/AndroidStudioProjects/newworld/DDComponentForAndroid/app/build/intermediates/classes/debug/com/mrzhang/component/MainActivity$1.class
    
    1 Field #14, name&type #45
    2 Method #15, name&type #46
    3 Long 100
    4 padding
    5 Method #47, name&type #48
    6 Class #49
    7 Method #6, name&type #50
    8 Class #51
    9 Method #15, name&type #52
    10 String #53
    11 Method #54, name&type #55
    12 Method #14, name&type #56
    13 Method #14, name&type #57
    14 Class #59
    15 Class #60
    16 UTF8 "this$0"
    17 UTF8 "Lcom/mrzhang/component/MainActivity;"
    18 UTF8 "<init>"
    19 UTF8 "(Lcom/mrzhang/component/MainActivity;)V"
    20 UTF8 "Code"
    21 UTF8 "LineNumberTable"
    22 UTF8 "LocalVariableTable"
    23 UTF8 "this"
    24 UTF8 "MyAsyncTask"
    25 UTF8 "InnerClasses"
    26 UTF8 "Lcom/mrzhang/component/MainActivity$MyAsyncTask;"
    27 UTF8 "doInBackground"
    28 UTF8 "([Ljava/lang/Object;)Ljava/lang/String;"
    29 UTF8 "e"
    30 UTF8 "Ljava/lang/InterruptedException;"
    31 UTF8 "params"
    32 UTF8 "[Ljava/lang/Object;"
    33 UTF8 "StackMapTable"
    34 Class #49
    35 UTF8 "onPostExecute"
    36 UTF8 "(Ljava/lang/String;)V"
    37 UTF8 "s"
    38 UTF8 "Ljava/lang/String;"
    39 UTF8 "(Ljava/lang/Object;)V"
    40 UTF8 "([Ljava/lang/Object;)Ljava/lang/Object;"
    41 UTF8 "Signature"
    42 UTF8 "Landroid/os/AsyncTask<Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;>;"
    43 UTF8 "SourceFile"
    44 UTF8 "MainActivity.java"
    45 NameAndType #16, type #17
    46 NameAndType #18, type #61
    47 Class #62
    48 NameAndType #63, type #64
    49 UTF8 "java/lang/InterruptedException"
    50 NameAndType #65, type #61
    51 UTF8 "java/lang/String"
    52 NameAndType #35, type #39
    53 UTF8 "zxx"
    54 Class #66
    55 NameAndType #67, type #68
    56 NameAndType #35, type #36
    57 NameAndType #27, type #28
    58 Class #69
    59 UTF8 "com/mrzhang/component/MainActivity$MyAsyncTask"
    60 UTF8 "android/os/AsyncTask"
    61 UTF8 "()V"
    62 UTF8 "java/lang/Thread"
    63 UTF8 "sleep"
    64 UTF8 "(J)V"
    65 UTF8 "printStackTrace"
    66 UTF8 "android/util/Log"
    67 UTF8 "d"
    68 UTF8 "(Ljava/lang/String;Ljava/lang/String;)I"
    69 UTF8 "com/mrzhang/component/MainActivity"
    ClassInfo{constPool=null, thisClass=14, accessFlags=32, superClass=15, interfaces=null, thisClassName='com.mrzhang.component.MainActivity$MyAsyncTask', major=51, minor=0}
    ClassDog find target in /Users/Smarking/AndroidStudioProjects/newworld/DDComponentForAndroid/app/build/intermediates/classes/debug/com/mrzhang/component/MainActivity$MyAsyncTask.class
    
    1 Method #47, name&type #87
    2 Method #47, name&type #88
    3 Class #90
    4 Integer 2130968603
    5 Method #46, name&type #92
    6 Class #93
    7 Integer 2131427414
    8 Method #46, name&type #95
    9 Class #96
    10 Field #46, name&type #97
    11 Integer 2131427415
    12 Field #46, name&type #98
    13 Method #9, name&type #99
    14 Class #100
    15 Method #14, name&type #101
    16 Method #46, name&type #102
    17 Field #46, name&type #103
    18 Method #46, name&type #104
    19 Method #105, name&type #106
    20 Field #46, name&type #107
    21 Method #108, name&type #109
    22 Method #108, name&type #110
    23 Method #111, name&type #112
    24 Class #113
    25 Method #114, name&type #115
    26 Method #111, name&type #116
    27 Interface #24, name&type #117
    28 Integer 2131427416
    29 Method #108, name&type #118
    30 Method #108, name&type #119
    31 Method #47, name&type #120
    32 Class #121
    33 Method #32, name&type #101
    34 Field #122, name&type #123
    35 Class #124
    36 Class #125
    37 Method #36, name&type #87
    38 String #126
    39 Method #36, name&type #127
    40 Method #36, name&type #128
    41 Method #36, name&type #129
    42 Method #122, name&type #130
    43 Method #131, name&type #132
    44 String #133
    45 Method #111, name&type #134
    46 Class #135
    47 Class #136
    48 Class #137
    49 UTF8 "MyAsyncTask"
    50 UTF8 "InnerClasses"
    51 UTF8 "fragment"
    52 UTF8 "Landroid/support/v4/app/Fragment;"
    53 UTF8 "ft"
    54 UTF8 "Landroid/support/v4/app/FragmentTransaction;"
    55 UTF8 "installReadBookBtn"
    56 UTF8 "Landroid/widget/Button;"
    57 UTF8 "uninstallReadBtn"
    58 UTF8 "<init>"
    59 UTF8 "()V"
    60 UTF8 "Code"
    61 UTF8 "LineNumberTable"
    62 UTF8 "LocalVariableTable"
    63 UTF8 "this"
    64 UTF8 "Lcom/mrzhang/component/MainActivity;"
    65 UTF8 "onCreate"
    66 UTF8 "(Landroid/os/Bundle;)V"
    67 UTF8 "savedInstanceState"
    68 UTF8 "Landroid/os/Bundle;"
    69 UTF8 "showFragment"
    70 UTF8 "service"
    71 UTF8 "Lcom/mrzhang/componentservice/readerbook/ReadBookService;"
    72 UTF8 "router"
    73 UTF8 "Lcom/mrzhang/component/componentlib/router/Router;"
    74 UTF8 "StackMapTable"
    75 Class #139
    76 UTF8 "onResume"
    77 UTF8 "asyncTask"
    78 UTF8 "Landroid/os/AsyncTask;"
    79 UTF8 "i"
    80 UTF8 "I"
    81 UTF8 "onClick"
    82 UTF8 "(Landroid/view/View;)V"
    83 UTF8 "v"
    84 UTF8 "Landroid/view/View;"
    85 UTF8 "SourceFile"
    86 UTF8 "MainActivity.java"
    87 NameAndType #58, type #59
    88 NameAndType #65, type #66
    89 Class #140
    90 UTF8 "com/mrzhang/component/R$layout"
    91 UTF8 "layout"
    92 NameAndType #141, type #142
    93 UTF8 "com/mrzhang/component/R$id"
    94 UTF8 "id"
    95 NameAndType #143, type #144
    96 UTF8 "android/widget/Button"
    97 NameAndType #55, type #56
    98 NameAndType #57, type #56
    99 NameAndType #145, type #146
    100 UTF8 "com/mrzhang/component/MainActivity$1"
    101 NameAndType #58, type #147
    102 NameAndType #69, type #59
    103 NameAndType #51, type #52
    104 NameAndType #148, type #149
    105 Class #150
    106 NameAndType #151, type #152
    107 NameAndType #53, type #54
    108 Class #153
    109 NameAndType #154, type #155
    110 NameAndType #156, type #157
    111 Class #139
    112 NameAndType #158, type #159
    113 UTF8 "com/mrzhang/componentservice/readerbook/ReadBookService"
    114 Class #160
    115 NameAndType #161, type #162
    116 NameAndType #163, type #164
    117 NameAndType #165, type #166
    118 NameAndType #167, type #168
    119 NameAndType #169, type #157
    120 NameAndType #76, type #59
    121 UTF8 "com/mrzhang/component/MainActivity$MyAsyncTask"
    122 Class #170
    123 NameAndType #171, type #172
    124 UTF8 "java/lang/Object"
    125 UTF8 "java/lang/StringBuilder"
    126 UTF8 "smarking "
    127 NameAndType #173, type #174
    128 NameAndType #173, type #175
    129 NameAndType #176, type #162
    130 NameAndType #177, type #178
    131 Class #179
    132 NameAndType #180, type #157
    133 UTF8 "com.mrzhang.share.applike.ShareApplike"
    134 NameAndType #181, type #182
    135 UTF8 "com/mrzhang/component/MainActivity"
    136 UTF8 "android/support/v7/app/AppCompatActivity"
    137 UTF8 "android/view/View$OnClickListener"
    138 UTF8 "OnClickListener"
    139 UTF8 "com/mrzhang/component/componentlib/router/Router"
    140 UTF8 "com/mrzhang/component/R"
    141 UTF8 "setContentView"
    142 UTF8 "(I)V"
    143 UTF8 "findViewById"
    144 UTF8 "(I)Landroid/view/View;"
    145 UTF8 "setOnClickListener"
    146 UTF8 "(Landroid/view/View$OnClickListener;)V"
    147 UTF8 "(Lcom/mrzhang/component/MainActivity;)V"
    148 UTF8 "getSupportFragmentManager"
    149 UTF8 "()Landroid/support/v4/app/FragmentManager;"
    150 UTF8 "android/support/v4/app/FragmentManager"
    151 UTF8 "beginTransaction"
    152 UTF8 "()Landroid/support/v4/app/FragmentTransaction;"
    153 UTF8 "android/support/v4/app/FragmentTransaction"
    154 UTF8 "remove"
    155 UTF8 "(Landroid/support/v4/app/Fragment;)Landroid/support/v4/app/FragmentTransaction;"
    156 UTF8 "commit"
    157 UTF8 "()I"
    158 UTF8 "getInstance"
    159 UTF8 "()Lcom/mrzhang/component/componentlib/router/Router;"
    160 UTF8 "java/lang/Class"
    161 UTF8 "getSimpleName"
    162 UTF8 "()Ljava/lang/String;"
    163 UTF8 "getService"
    164 UTF8 "(Ljava/lang/String;)Ljava/lang/Object;"
    165 UTF8 "getReadBookFragment"
    166 UTF8 "()Landroid/support/v4/app/Fragment;"
    167 UTF8 "add"
    168 UTF8 "(ILandroid/support/v4/app/Fragment;)Landroid/support/v4/app/FragmentTransaction;"
    169 UTF8 "commitAllowingStateLoss"
    170 UTF8 "android/os/AsyncTask"
    171 UTF8 "THREAD_POOL_EXECUTOR"
    172 UTF8 "Ljava/util/concurrent/Executor;"
    173 UTF8 "append"
    174 UTF8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"
    175 UTF8 "(I)Ljava/lang/StringBuilder;"
    176 UTF8 "toString"
    177 UTF8 "executeOnExecutor"
    178 UTF8 "(Ljava/util/concurrent/Executor;[Ljava/lang/Object;)Landroid/os/AsyncTask;"
    179 UTF8 "android/view/View"
    180 UTF8 "getId"
    181 UTF8 "registerComponent"
    182 UTF8 "(Ljava/lang/String;)V"
    ClassInfo{constPool=null, thisClass=46, accessFlags=33, superClass=47, interfaces=[48], thisClassName='com.mrzhang.component.MainActivity', major=51, minor=0}
    ClassDog find target in /Users/Smarking/AndroidStudioProjects/newworld/DDComponentForAndroid/app/build/intermediates/classes/debug/com/mrzhang/component/MainActivity.class
    
    
    java文件内容
    
    
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentTransaction;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        Fragment fragment;
        FragmentTransaction ft;
    
        Button installReadBookBtn;
        Button uninstallReadBtn;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            installReadBookBtn = (Button) findViewById(R.id.install_share);
            uninstallReadBtn = (Button) findViewById(R.id.uninstall_share);
            installReadBookBtn.setOnClickListener(this);
            uninstallReadBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Router.unregisterComponent("com.mrzhang.share.applike.ShareApplike");
                }
            });
            showFragment();
        }
    
        private void showFragment() {
            if (fragment != null) {
                ft = getSupportFragmentManager().beginTransaction();
                ft.remove(fragment).commit();
                fragment = null;
            }
            Router router = Router.getInstance();
            if (router.getService(ReadBookService.class.getSimpleName()) != null) {
                ReadBookService service = (ReadBookService) router.getService(ReadBookService.class.getSimpleName());
                fragment = service.getReadBookFragment();
                ft = getSupportFragmentManager().beginTransaction();
                ft.add(R.id.tab_content, fragment).commitAllowingStateLoss();
            }
        }
    
        @Override
        protected void onResume() {
            super.onResume();
    
            for (int i = 0; i < 100; i++) {
                AsyncTask asyncTask = new MyAsyncTask();
                asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "smarking " + i);
            }
        }
    
    
        class MyAsyncTask extends AsyncTask<Object, String, String> {
    
            @Override
            protected String doInBackground(Object[] params) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return (String) params[0];
            }
    
            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                Log.d("zxx", s);
            }
        }
    
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.install_share:
                    Router.registerComponent("com.ShareApplike");
                    break;
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:JVM-Class

          本文链接:https://www.haomeiwen.com/subject/snuywxtx.html