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

    Class文件的解析过程,简版如上,完全是根据ClassFile.java定义的数据格式解析的。常量池存放了当前类...

  • JVM-Class文件结构

    一.Class文件 注意:任何一个Class文件都对应着唯一一个类或接口的定义信息,但反过来说,类或接口并不一定都...

  • 深入JVM-Class装载系统

    一、Class文件的装载过程 Class类型通常以文件的形式存在(当然,任何二进制流都可以是Class类型),只有...

  • 深入理解JVM-Class文件结构和类加载

    先谈谈JVM 这篇文章主要是讲class文件和类加载机制,但是整个过程都和jvm密切相关,所以先从jvm说起。 J...

网友评论

      本文标题:JVM-Class

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