小傅哥 | https://bugstack.cn
沉淀、分享、成长,专注于原创专题案例,以最易学习编程的方式分享知识,让自己和他人都能有所收获。目前已完成的专题有;Netty4.x实战专题案例、用Java实现JVM、基于JavaAgent的全链路监控、手写RPC框架、架构设计专题案例、源码分析等。
你用剑 、我用刀 ,好的代码都很烧,望你不吝出招!
一、案例介绍
异常处理是java语言非常重要的一个语法,本章主要实现如何处理抛出的异常。
在Java语言中,异常可以分为两类:Checked异常和Unchecked异常。Unchecked异常包括java.lang.RuntimeException、java.lang.Error以及它们的子类,提前异常都是Checked异常。所有异常都最终继承自java.lang.Throwable。如果一个方法有可能导致Checked异常抛出,则该方法要么需要捕获该异常并妥善处理,要么必须把该异常列在自己的throws子句中,否则无法通过编译。Unchanged异常没有这个限制。请注意,Java虚拟机规范并没有这个规定,这只是Java语言的语法规则。
异常可以由Java虚拟机抛出,也可以由Java代码抛出。当Java虚拟机在运行过程中遇到比较严重的问题时,会抛出java.lang.Error的某个子类,如StackOverflowError、OutOfMemoryError等。程序一般无法从这种异常里恢复,所以在代码中通常也不必关心这类异常。
一部分执行在执行过程中会导致Java虚拟机抛出java.lang.RuntimeException的某个子类,如NullPointerException、IndexOutOfBoundsException等。这类异常一般是代码中的bug导致的,需要格外注意。在代码中抛出和处理异常是由athrow指令和方法的异常处理表配合完成的。
二、环境准备
- jdk 1.8.0
- IntelliJ IDEA Community Edition 2018.3.1 x64
三、配置信息
- 调试配置
11. 配置位置:Run/Debug Configurations -> program arguments
12. 配置内容:-Xjre "C:Program FilesJavajdk1.8.0_161jre" E:itstackgitistack-demoitstack-demo-jvmitstack-demo-jvm-10targettest-classesorgitstackdemotestHelloWorld
四、代码示例
1itstack-demo-jvm-10
2
3├── pom.xml
4
5└── src
6
7 └── main
8
9 │ └── java
10
11 │ └── org.itstack.demo.jvm
12
13 │ ├── _native
14
15 │ │ ├── java
16
17 │ │ │ ├── _Class.java
18
19 │ │ │ ├── _Double.java
20
21 │ │ │ ├── _Float.java
22
23 │ │ │ ├── _Object.java
24
25 │ │ │ ├── _String.java
26
27 │ │ │ ├── _System.java
28
29 │ │ │ └── _Throwable.java
30
31 │ │ └── sun
32
33 │ ├── NativeMethod.java
34
35 │ └── Registry.java
36
37 │ ├── classfile
38
39 │ │ ├── attributes
40
41 │ │ ├── constantpool
42
43 │ │ ├── ClassFile.java
44
45 │ │ ├── ClassReader.java
46
47 │ │ └── MemberInfo.java
48
49 │ ├── classpath
50
51 │ │ ├── impl
52
53 │ │ │ ├── CompositeEntry.java
54
55 │ │ │ ├── DirEntry.java
56
57 │ │ │ ├── WildcardEntry.java
58
59 │ │ │ └── ZipEntry.java
60
61 │ │ ├── Classpath.java
62
63 │ │ └── Entry.java
64
65 │ ├── classpath
66
67 │ │ ├── base
68
69 │ │ │ ├── BytecodeReader.java
70
71 │ │ │ ├── ClassInitLogic.java
72
73 │ │ │ ├── Instruction.java
74
75 │ │ │ ├── InstructionBranch.java
76
77 │ │ │ ├── InstructionIndex8.java
78
79 │ │ │ ├── InstructionIndex16.java
80
81 │ │ │ ├── InstructionNoOperands.java
82
83 │ │ │ └── MethodInvokeLogic.java
84
85 │ │ ├── comparisons
86
87 │ │ ├── constants
88
89 │ │ ├── control
90
91 │ │ ├── conversions
92
93 │ │ ├── extended
94
95 │ │ ├── loads
96
97 │ │ ├── math
98
99 │ │ ├── references
100
101 │ │ │ ├── ANEW_ARRAY.java
102
103 │ │ │ ├── ARRAY_LENGTH.java
104
105 │ │ │ ├── ATHROW.java
106
107 │ │ │ ├── CHECK_CAST.java
108
109 │ │ │ ├── GET_FIELD.java
110
111 │ │ │ ├── GET_STATIC.java
112
113 │ │ │ ├── INSTANCE_OF.java
114
115 │ │ │ ├── INVOKE_INTERFACE.java
116
117 │ │ │ ├── INVOKE_SPECIAL.java
118
119 │ │ │ ├── INVOKE_STATIC.java
120
121 │ │ │ ├── INVOKE_VIRTUAL.java
122
123 │ │ │ ├── MULTI_ANEW_ARRAY.java
124
125 │ │ │ ├── NEW.java
126
127 │ │ │ ├── NEW_ARRAY.java
128
129 │ │ │ ├── PUT_FIELD.java
130
131 │ │ │ └── PUT_STATIC.java
132
133 │ │ ├── reserved
134
135 │ │ │ └── INVOKE_NATIVE.java
136
137 │ │ ├── stack
138
139 │ │ ├── store
140
141 │ │ │ └── xastore
142
143 │ │ │ ├── AASTORE.java
144
145 │ │ │ ├── BASTORE.java
146
147 │ │ │ ├── CASTORE.java
148
149 │ │ │ ├── DASTORE.java
150
151 │ │ │ ├── FASTORE.java
152
153 │ │ │ ├── IASTORE.java
154
155 │ │ │ ├── LASTORE.java
156
157 │ │ │ └── SASTORE.java
158
159 │ │ └── Factory
160
161 │ ├── rtda
162
163 │ │ ├── heap
164
165 │ │ │ ├── constantpool
166
167 │ │ │ ├── methodarea
168
169 │ │ │ │ ├── Class.java
170
171 │ │ │ │ ├── ClassMember.java
172
173 │ │ │ │ ├── ExceptionTable.java
174
175 │ │ │ │ ├── Field.java
176
177 │ │ │ │ ├── Method.java
178
179 │ │ │ │ ├── MethodDescriptor.java
180
181 │ │ │ │ ├── MethodDescriptorParser.java
182
183 │ │ │ │ ├── MethodLookup.java
184
185 │ │ │ │ ├── Object.java
186
187 │ │ │ │ ├── Slots.java
188
189 │ │ │ │ └── StringPool.java
190
191 │ │ │ └── ClassLoader.java
192
193 │ │ ├── Frame.java
194
195 │ │ ├── JvmStack.java
196
197 │ │ ├── LocalVars.java
198
199 │ │ ├── OperandStack.java
200
201 │ │ ├── Slot.java
202
203 │ │ └── Thread.java
204
205 │ ├── Cmd.java
206
207 │ ├── Interpret.java
208
209 │ └── Main.java
210
211 └── test
212
213 └── java
214
215 └── org.itstack.demo.test
216
217 └── HelloWorld.java
*如下为新增代码:*
ClassReader.java (优化)
1/**
2
3 * https://bugstack.cn/
4
5 * create by fuzhengwei on 2019/5/12
6
7 * <p>
8
9 * java虚拟机定义了u1、u2、u4三种数据类型来表示;1字节、2字节、4字节,无符号整数。
10
11 * 在如下实现中,用增位方式表示无符号类型:
12
13 * u1、u2可以用int类型存储,因为int类型是4字节
14
15 * u4 需要用long类型存储,因为long类型是8字节
16
17 */
18
19public class ClassReader {
20
21
22
23 private byte[] data;
24
25
26
27 public ClassReader(byte[] data) {
28
29 this.data = data;
30
31 }
32
33
34
35 //u1
36
37 public int readUint8() {
38
39 byte[] val = readByte(1);
40
41 return byte2int(val);
42
43 }
44
45
46
47 //u2
48
49 public int readUint16() {
50
51 byte[] val = readByte(2);
52
53 return byte2int(val);
54
55 }
56
57
58
59 //u4
60
61 public long readUint32() {
62
63 byte[] val = readByte(4);
64
65 String str_hex = new BigInteger(1, val).toString(16);
66
67 return Long.parseLong(str_hex, 16);
68
69 }
70
71
72
73 public int readUint32TInteger(){
74
75 byte[] val = readByte(4);
76
77 return new BigInteger(1, val).intValue();
78
79 }
80
81
82
83 public float readUint64TFloat() {
84
85 byte[] val = readByte(8);
86
87 return new BigInteger(1, val).floatValue();
88
89 }
90
91
92
93 public long readUint64TLong() {
94
95 byte[] val = readByte(8);
96
97 return new BigInteger(1, val).longValue();
98
99 }
100
101
102
103 public double readUint64TDouble() {
104
105 byte[] val = readByte(8);
106
107 return new BigInteger(1, val).doubleValue();
108
109 }
110
111
112
113 public int[] readUint16s() {
114
115 int n = this.readUint16();
116
117 int[] s = new int[n];
118
119 for (int i = 0; i < n; i++) {
120
121 s[i] = this.readUint16();
122
123 }
124
125 return s;
126
127 }
128
129
130
131 public byte[] readBytes(int n) {
132
133 return readByte(n);
134
135 }
136
137
138
139 private byte[] readByte(int length) {
140
141 byte[] copy = new byte[length];
142
143 System.arraycopy(data, 0, copy, 0, length);
144
145 System.arraycopy(data, length, data, 0, data.length - length);
146
147 return copy;
148
149 }
150
151
152
153 private int byte2int(byte[] val) {
154
155 String str_hex = new BigInteger(1, val).toString(16);
156
157 return Integer.parseInt(str_hex, 16);
158
159 }
160
161
162
163}
_Throwable.java
1public class _Throwable {
2
3
4
5 private StackTraceElement stackTraceElement;
6
7
8
9 private final String jlThrowable = "java/lang/Throwable";
10
11
12
13 public _Throwable() {
14
15 Registry.register(jlThrowable, "fillInStackTrace", "(I)Ljava/lang/Throwable;", new NativeMethod(this, "fillInStackTrace"));
16
17 Registry.register(jlThrowable, "registerNatives", "()V", new NativeMethod(this, "registerNatives"));
18
19 }
20
21
22
23 public void registerNatives(Frame frame) {
24
25 // do nothing
26
27 }
28
29
30
31 public String string() {
32
33 return String.format("%s.%s(%s:%d)", this.stackTraceElement.className, this.stackTraceElement.methodName, this.stackTraceElement.fileName, this.stackTraceElement.lineNumber);
34
35 }
36
37
38
39 public void fillInStackTrace(Frame frame) {
40
41 Object thiz = frame.localVars().getThis();
42
43 frame.operandStack().pushRef(thiz);
44
45
46
47 _Throwable[] stes = createStackTraceElements(thiz, frame.thread());
48
49 thiz.setExtra(stes);
50
51 }
52
53
54
55 private _Throwable[] createStackTraceElements(Object tObj, Thread thread) {
56
57 int skip = distanceToObject(tObj.clazz()) + 2;
58
59 Frame[] frames = thread.getFrames();
60
61 _Throwable[] stes = new _Throwable[frames.length - skip];
62
63 int idx = 0;
64
65 for (int i = skip; i < frames.length; i++) {
66
67 stes[idx] = createStackTraceElement(frames[i]);
68
69 }
70
71 return stes;
72
73 }
74
75
76
77 private int distanceToObject(Class clazz) {
78
79 int distance = 0;
80
81 for (Class c = clazz.superClass(); c != null; c = c.superClass()) {
82
83 distance++;
84
85 }
86
87 return distance;
88
89 }
90
91
92
93 private _Throwable createStackTraceElement(Frame frame) {
94
95 Method method = frame.method();
96
97 Class clazz = method.clazz();
98
99 StackTraceElement stackTraceElement = new StackTraceElement();
100
101 stackTraceElement.fileName = clazz.sourceFile();
102
103 stackTraceElement.className = clazz.javaName();
104
105 stackTraceElement.methodName = method.name();
106
107 stackTraceElement.lineNumber = method.getLineNumber(frame.nextPC() - 1);
108
109 _Throwable throwable = new _Throwable();
110
111 throwable.stackTraceElement = stackTraceElement;
112
113 return throwable;
114
115 }
116
117
118
119 private class StackTraceElement {
120
121 private String fileName;
122
123 private String className;
124
125 private String methodName;
126
127 private int lineNumber;
128
129 }
130
131
132
133}
ATHROW.java
1public class ATHROW extends InstructionNoOperands {
2
3
4
5 @Override
6
7 public void execute(Frame frame) {
8
9 Object ex = frame.operandStack().popRef();
10
11 if (ex == null) {
12
13 throw new NullPointerException();
14
15 }
16
17
18
19 Thread thread = frame.thread();
20
21 if (!findAndGotoExceptionHandler(thread, ex)) {
22
23 handleUncaughtException(thread, ex);
24
25 }
26
27 }
28
29
30
31 private boolean findAndGotoExceptionHandler(Thread thread, Object ex) {
32
33 do {
34
35 Frame frame = thread.currentFrame();
36
37 int pc = frame.nextPC() - 1;
38
39
40
41 int handlerPc = frame.method().findExceptionHandler(ex.clazz(), pc);
42
43 if (handlerPc > 0) {
44
45 OperandStack stack = frame.operandStack();
46
47 stack.clear();
48
49 stack.pushRef(ex);
50
51 frame.setNextPC(handlerPc);
52
53 return true;
54
55 }
56
57
58
59 thread.popFrame();
60
61 } while (!thread.isStackEmpty());
62
63 return false;
64
65 }
66
67
68
69 private void handleUncaughtException(Thread thread, Object ex) {
70
71 thread.clearStack();
72
73
74
75 Object jMsg = ex.getRefVar("detailMessage", "Ljava/lang/String;");
76
77
78
79 String msg = StringPool.goString(jMsg);
80
81
82
83 System.out.println(ex.clazz().javaName() + ":" + msg);
84
85
86
87 java.lang.Object extra = ex.extra();
88
89
90
91 _Throwable[] throwables = (_Throwable[]) extra;
92
93 for (_Throwable t : throwables) {
94
95 System.out.println(t.string());
96
97 }
98
99
100
101 }
102
103
104
105}
ExceptionTable.java
1public class ExceptionTable {
2
3
4
5 private ExceptionHandler[] exceptionTable;
6
7
8
9 public ExceptionTable(CodeAttribute.ExceptionTableEntry[] entries, RunTimeConstantPool runTimeConstantPool) {
10
11 this.exceptionTable = new ExceptionHandler[entries.length];
12
13 int i = 0;
14
15 for (CodeAttribute.ExceptionTableEntry entry : entries) {
16
17 ExceptionHandler handler = new ExceptionHandler(
18
19 entry.startPC(),
20
21 entry.endPC(),
22
23 entry.handlerPC(),
24
25 getCatchType(entry.catchType(), runTimeConstantPool)
26
27 );
28
29 this.exceptionTable[i++] = handler;
30
31 }
32
33 }
34
35
36
37 public ClassRef getCatchType(int idx, RunTimeConstantPool runTimeConstantPool) {
38
39 if (idx == 0) return null;
40
41 return (ClassRef) runTimeConstantPool.getConstants(idx);
42
43 }
44
45
46
47 public ExceptionHandler findExceptionHandler(Class exClass, int pc) {
48
49 for (ExceptionHandler handler : exceptionTable) {
50
51 if (pc >= handler.startPC && pc < handler.endPC) {
52
53 if (null == handler.catchType) {
54
55 return handler;
56
57 }
58
59 Class catchClass = handler.catchType.resolvedClass();
60
61 if (catchClass == exClass || catchClass.isSubClassOf(exClass)) {
62
63 return handler;
64
65 }
66
67 }
68
69 }
70
71 return null;
72
73 }
74
75
76
77
78
79 class ExceptionHandler {
80
81
82
83 int startPC;
84
85 int endPC;
86
87 int handlerPC;
88
89 ClassRef catchType;
90
91
92
93 ExceptionHandler(int startPC, int endPC, int handlerPC, ClassRef catchType) {
94
95 this.startPC = startPC;
96
97 this.endPC = endPC;
98
99 this.handlerPC = handlerPC;
100
101 this.catchType = catchType;
102
103 }
104
105 }
106
107
108
109}
Method.java
1public class Method extends ClassMember {
2
3
4
5 public int maxStack;
6
7 public int maxLocals;
8
9 public byte[] code;
10
11 private ExceptionTable exceptionTable;
12
13 private LineNumberTableAttribute lineNumberTable;
14
15 private int argSlotCount;
16
17
18
19 Method[] newMethods(Class clazz, MemberInfo[] cfMethods) {
20
21 Method[] methods = new Method[cfMethods.length];
22
23 for (int i = 0; i < cfMethods.length; i++) {
24
25 methods[i] = newMethod(clazz, cfMethods[i]);
26
27 }
28
29 return methods;
30
31 }
32
33
34
35 private Method newMethod(Class clazz, MemberInfo cfMethod) {
36
37 Method method = new Method();
38
39 method.clazz = clazz;
40
41 method.copyMemberInfo(cfMethod);
42
43 method.copyAttributes(cfMethod);
44
45 MethodDescriptor md = MethodDescriptorParser.parseMethodDescriptorParser(method.descriptor);
46
47 method.calcArgSlotCount(md.parameterTypes);
48
49 if (method.isNative()) {
50
51 method.injectCodeAttribute(md.returnType);
52
53 }
54
55 return method;
56
57 }
58
59
60
61 private void injectCodeAttribute(String returnType) {
62
63 this.maxStack = 4; //todo
64
65 this.maxLocals = this.argSlotCount;
66
67
68
69 switch (returnType.getBytes()[0]) {
70
71 case 'V':
72
73 this.code = new byte[]{(byte) 0xfe, (byte) 0xb1};
74
75 break;
76
77 case 'L':
78
79 case '[':
80
81 this.code = new byte[]{(byte) 0xfe, (byte) 0xb0};
82
83 break;
84
85 case 'D':
86
87 this.code = new byte[]{(byte) 0xfe, (byte) 0xaf};
88
89 break;
90
91 case 'F':
92
93 this.code = new byte[]{(byte) 0xfe, (byte) 0xae};
94
95 break;
96
97 case 'J':
98
99 this.code = new byte[]{(byte) 0xfe, (byte) 0xad};
100
101 break;
102
103 default:
104
105 this.code = new byte[]{(byte) 0xfe, (byte) 0xac};
106
107 break;
108
109 }
110
111 }
112
113
114
115 private void copyAttributes(MemberInfo cfMethod) {
116
117 CodeAttribute codeAttr = cfMethod.codeAttribute();
118
119 if (null != codeAttr) {
120
121 this.maxStack = codeAttr.maxStack();
122
123 this.maxLocals = codeAttr.maxLocals();
124
125 this.code = codeAttr.data();
126
127 this.lineNumberTable = codeAttr.lineNumberTableAttribute();
128
129 this.exceptionTable = new ExceptionTable(codeAttr.exceptionTable(), this.clazz.constantPool());
130
131 }
132
133 }
134
135
136
137 private void calcArgSlotCount(List<String> parameterTypes) {
138
139 for (String paramType : parameterTypes) {
140
141 this.argSlotCount++;
142
143 if ("J".equals(paramType) || "D".equals(paramType)) {
144
145 this.argSlotCount++;
146
147 }
148
149 }
150
151 if (!this.isStatic()) {
152
153 this.argSlotCount++;
154
155 }
156
157 }
158
159
160
161 public boolean isSynchronized() {
162
163 return 0 != (this.accessFlags & AccessFlags.ACC_SYNCHRONIZED);
164
165 }
166
167
168
169 public boolean isBridge() {
170
171 return 0 != (this.accessFlags & AccessFlags.ACC_BRIDGE);
172
173 }
174
175
176
177 public boolean isVarargs() {
178
179 return 0 != (this.accessFlags & AccessFlags.ACC_VARARGS);
180
181 }
182
183
184
185 public boolean isNative() {
186
187 return 0 != (this.accessFlags & AccessFlags.ACC_NATIVE);
188
189 }
190
191
192
193 public boolean isAbstract() {
194
195 return 0 != (this.accessFlags & AccessFlags.ACC_ABSTRACT);
196
197 }
198
199
200
201 public boolean isStrict() {
202
203 return 0 != (this.accessFlags & AccessFlags.ACC_STRICT);
204
205 }
206
207
208
209 public int maxStack() {
210
211 return this.maxStack;
212
213 }
214
215
216
217 public int maxLocals() {
218
219 return this.maxLocals;
220
221 }
222
223
224
225 public byte[] code() {
226
227 return this.code;
228
229 }
230
231
232
233 public int argSlotCount() {
234
235 return this.argSlotCount;
236
237 }
238
239
240
241 public int findExceptionHandler(Class exClass, int pc) {
242
243 ExceptionTable.ExceptionHandler handler = this.exceptionTable.findExceptionHandler(exClass, pc);
244
245 if (handler != null) {
246
247 return handler.handlerPC;
248
249 }
250
251 return -1;
252
253 }
254
255
256
257 public int getLineNumber(int pc) {
258
259 if (this.isNative()) return -2;
260
261 if (this.lineNumberTable == null) return -1;
262
263 return this.lineNumberTable.getLineNumber(pc);
264
265 }
266
267
268
269}
HelloWorld.java
1public class HelloWorld {
2
3
4
5 public static void main(String[] args) {
6
7 throw new RuntimeException("自定义异常");
8
9 }
10
11
12
13}
五、测试结果
-Xjre "C:Program FilesJavajdk1.8.0_161jre" E:itstackgitistack-demoitstack-demo-jvmitstack-demo-jvm-10targettest-classesorgitstackdemotestHelloWorld -verbose
1public class org.itstack.demo.test.HelloWorld {
2
3 public org.itstack.demo.test.HelloWorld();
4
5 Code:
6
7 0: aload_0
8
9 1: invokespecial #1 // Method java/lang/Object."<init>":()V
10
11 4: return
12
13
14
15 public static void main(java.lang.String[]);
16
17 Code:
18
19 0: new #2 // class java/lang/RuntimeException
20
21 3: dup
22
23 4: ldc #3 // String 自定义异常
24
25 6: invokespecial #4 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
26
27 9: athrow
28
29}
1org/itstack/demo/test/HelloWorld.main() 寄存器(指令):0xbb -> NEW
2
3java/lang/Object.<clinit>() 寄存器(指令):0xb8 -> INVOKE_STATIC
4
5java/lang/Object.registerNatives() 寄存器(指令):0xfe -> INVOKE_NATIVE
6
7java/lang/Object.registerNatives() 寄存器(指令):0xb1 -> RETURN
8
9java/lang/Object.<clinit>() 寄存器(指令):0xb1 -> RETURN
10
11java/lang/Throwable.<clinit>() 寄存器(指令):0x12 -> LDC
12
13java/lang/Throwable.<clinit>() 寄存器(指令):0xb6 -> INVOKE_VIRTUAL
14
15java/lang/Class.desiredAssertionStatus() 寄存器(指令):0x2a -> ALOAD_0
16
17java/lang/Class.desiredAssertionStatus() 寄存器(指令):0xb6 -> INVOKE_VIRTUAL
18
19java/lang/Class.getClassLoader() 寄存器(指令):0x2a -> ALOAD_0
20
21java/lang/Class.getClassLoader() 寄存器(指令):0xb6 -> INVOKE_VIRTUAL
22
23java/lang/Class.getClassLoader0() 寄存器(指令):0x2a -> ALOAD_0
24
25java/lang/Class.getClassLoader0() 寄存器(指令):0xb4 -> GET_FIELD
417java/lang/Class.desiredAssertionStatus() 寄存器(指令):0xb6 -> INVOKE_VIRTUAL
418
419java/lang/Class.getClassLoader() 寄存器(指令):0x2a -> ALOAD_0
420
421java/lang/Class.getClassLoader() 寄存器(指令):0xb6 -> INVOKE_VIRTUAL
422
423java/lang/Class.getClassLoader0() 寄存器(指令):0x2a -> ALOAD_0
424
425java/lang/Class.getClassLoader0() 寄存器(指令):0xb4 -> GET_FIELD
426
427java/lang/Class.getClassLoader0() 寄存器(指令):0xb0 -> ARETURN
428
429java/lang/Class.getClassLoader() 寄存器(指令):0x4c -> ASTORE_1
430
431java/lang/Class.getClassLoader() 寄存器(指令):0x2b -> ALOAD_1
432
433java/lang/Class.getClassLoader() 寄存器(指令):0xc7 -> IFNONNULL
434
435java/lang/Class.getClassLoader() 寄存器(指令):0x01 -> ACONST_NULL
436
437java/lang/Class.getClassLoader() 寄存器(指令):0xb0 -> ARETURN
438
439java/lang/Class.desiredAssertionStatus() 寄存器(指令):0x4c -> ASTORE_1
440
441java/lang/Class.desiredAssertionStatus() 寄存器(指令):0x2b -> ALOAD_1
442
443java/lang/Class.desiredAssertionStatus() 寄存器(指令):0xc7 -> IFNONNULL
444
445java/lang/Class.desiredAssertionStatus() 寄存器(指令):0x2a -> ALOAD_0
446
447java/lang/Class.desiredAssertionStatus() 寄存器(指令):0xb8 -> INVOKE_STATIC
448
449java/lang/Class.desiredAssertionStatus0() 寄存器(指令):0xfe -> INVOKE_NATIVE
450
451java/lang/Class.desiredAssertionStatus0() 寄存器(指令):0xac -> IRETURN
452
453java/lang/Class.desiredAssertionStatus() 寄存器(指令):0xac -> IRETURN
454
455java/lang/Throwable.<clinit>() 寄存器(指令):0x9a -> IFNE
456
457java/lang/Throwable.<clinit>() 寄存器(指令):0x04 -> ICONST_1
458
459java/lang/Throwable.<clinit>() 寄存器(指令):0xa7 -> GOTO
460
461java/lang/Throwable.<clinit>() 寄存器(指令):0xb3 -> PUT_STATIC
462
463java/lang/Throwable.<clinit>() 寄存器(指令):0x03 -> ICONST_0
464
465java/lang/Throwable.<clinit>() 寄存器(指令):0xbd -> ANEW_ARRAY
466
467java/lang/Throwable.<clinit>() 寄存器(指令):0xb3 -> PUT_STATIC
468
469java/lang/Throwable.<clinit>() 寄存器(指令):0xbb -> NEW
470
471java/lang/Throwable.<clinit>() 寄存器(指令):0x59 -> DUP
472
473java/lang/Throwable.<clinit>() 寄存器(指令):0x03 -> ICONST_0
474
475java/lang/Throwable.<clinit>() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
476
477java/util/ArrayList.<init>() 寄存器(指令):0x2a -> ALOAD_0
478
479java/util/ArrayList.<init>() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
480
481java/util/AbstractList.<init>() 寄存器(指令):0x2a -> ALOAD_0
482
483java/util/AbstractList.<init>() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
484
485java/util/AbstractCollection.<init>() 寄存器(指令):0x2a -> ALOAD_0
486
487java/util/AbstractCollection.<init>() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
488
489java/lang/Object.<init>() 寄存器(指令):0xb1 -> RETURN
490
491java/util/AbstractCollection.<init>() 寄存器(指令):0xb1 -> RETURN
492
493java/util/AbstractList.<init>() 寄存器(指令):0x2a -> ALOAD_0
494
495java/util/AbstractList.<init>() 寄存器(指令):0x03 -> ICONST_0
496
497java/util/AbstractList.<init>() 寄存器(指令):0xb5 -> PUT_FIELD
498
499java/util/AbstractList.<init>() 寄存器(指令):0xb1 -> RETURN
500
501java/util/ArrayList.<init>() 寄存器(指令):0x1b -> ILOAD_1
502
503java/util/ArrayList.<init>() 寄存器(指令):0x9e -> IFLE
504
505java/util/ArrayList.<init>() 寄存器(指令):0x1b -> ILOAD_1
506
507java/util/ArrayList.<init>() 寄存器(指令):0x9a -> IFNE
508
509java/util/ArrayList.<init>() 寄存器(指令):0x2a -> ALOAD_0
510
511java/util/ArrayList.<init>() 寄存器(指令):0xb2 -> GET_STATIC
512
513java/util/ArrayList.<init>() 寄存器(指令):0xb5 -> PUT_FIELD
514
515java/util/ArrayList.<init>() 寄存器(指令):0xa7 -> GOTO
516
517java/util/ArrayList.<init>() 寄存器(指令):0xb1 -> RETURN
518
519java/lang/Throwable.<clinit>() 寄存器(指令):0xb8 -> INVOKE_STATIC
520
521java/util/Collections.unmodifiableList() 寄存器(指令):0x2a -> ALOAD_0
522
523java/util/Collections.unmodifiableList() 寄存器(指令):0xc1 -> INSTANCE_OF
524
525java/util/Collections.unmodifiableList() 寄存器(指令):0x99 -> IFEQ
526
527java/util/Collections.unmodifiableList() 寄存器(指令):0xbb -> NEW
528
529java/util/Collections.unmodifiableList() 寄存器(指令):0x59 -> DUP
530
531java/util/Collections.unmodifiableList() 寄存器(指令):0x2a -> ALOAD_0
532
533java/util/Collections.unmodifiableList() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
534
535java/util/Collections$UnmodifiableList.<init>() 寄存器(指令):0x2a -> ALOAD_0
536
537java/util/Collections$UnmodifiableList.<init>() 寄存器(指令):0x2b -> ALOAD_1
538
539java/util/Collections$UnmodifiableList.<init>() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
540
541java/util/Collections$UnmodifiableCollection.<init>() 寄存器(指令):0x2a -> ALOAD_0
542
543java/util/Collections$UnmodifiableCollection.<init>() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
544
545java/lang/Object.<init>() 寄存器(指令):0xb1 -> RETURN
546
547java/util/Collections$UnmodifiableCollection.<init>() 寄存器(指令):0x2b -> ALOAD_1
548
549java/util/Collections$UnmodifiableCollection.<init>() 寄存器(指令):0xc7 -> IFNONNULL
550
551java/util/Collections$UnmodifiableCollection.<init>() 寄存器(指令):0x2a -> ALOAD_0
552
553java/util/Collections$UnmodifiableCollection.<init>() 寄存器(指令):0x2b -> ALOAD_1
554
555java/util/Collections$UnmodifiableCollection.<init>() 寄存器(指令):0xb5 -> PUT_FIELD
556
557java/util/Collections$UnmodifiableCollection.<init>() 寄存器(指令):0xb1 -> RETURN
558
559java/util/Collections$UnmodifiableList.<init>() 寄存器(指令):0x2a -> ALOAD_0
560
561java/util/Collections$UnmodifiableList.<init>() 寄存器(指令):0x2b -> ALOAD_1
562
563java/util/Collections$UnmodifiableList.<init>() 寄存器(指令):0xb5 -> PUT_FIELD
564
565java/util/Collections$UnmodifiableList.<init>() 寄存器(指令):0xb1 -> RETURN
566
567java/util/Collections.unmodifiableList() 寄存器(指令):0xb0 -> ARETURN
568
569java/lang/Throwable.<clinit>() 寄存器(指令):0xb3 -> PUT_STATIC
570
571java/lang/Throwable.<clinit>() 寄存器(指令):0x03 -> ICONST_0
572
573java/lang/Throwable.<clinit>() 寄存器(指令):0xbd -> ANEW_ARRAY
574
575java/lang/Throwable.<clinit>() 寄存器(指令):0xb3 -> PUT_STATIC
576
577java/lang/Throwable.<clinit>() 寄存器(指令):0xb1 -> RETURN
578
579java/lang/Throwable.<clinit>() 寄存器(指令):0x12 -> LDC
580
581java/lang/Throwable.<clinit>() 寄存器(指令):0xb6 -> INVOKE_VIRTUAL
582
583java/lang/Class.desiredAssertionStatus() 寄存器(指令):0x2a -> ALOAD_0
584
585java/lang/Class.desiredAssertionStatus() 寄存器(指令):0xb6 -> INVOKE_VIRTUAL
586
587java/lang/Class.getClassLoader() 寄存器(指令):0x2a -> ALOAD_0
588
589java/lang/Class.getClassLoader() 寄存器(指令):0xb6 -> INVOKE_VIRTUAL
590
591java/lang/Class.getClassLoader0() 寄存器(指令):0x2a -> ALOAD_0
592
593java/lang/Class.getClassLoader0() 寄存器(指令):0xb4 -> GET_FIELD
594
595java/lang/Class.getClassLoader0() 寄存器(指令):0xb0 -> ARETURN
596
597java/lang/Class.getClassLoader() 寄存器(指令):0x4c -> ASTORE_1
598
599java/lang/Class.getClassLoader() 寄存器(指令):0x2b -> ALOAD_1
600
601java/lang/Class.getClassLoader() 寄存器(指令):0xc7 -> IFNONNULL
602
603java/lang/Class.getClassLoader() 寄存器(指令):0x01 -> ACONST_NULL
604
605java/lang/Class.getClassLoader() 寄存器(指令):0xb0 -> ARETURN
606
607java/lang/Class.desiredAssertionStatus() 寄存器(指令):0x4c -> ASTORE_1
608
609java/lang/Class.desiredAssertionStatus() 寄存器(指令):0x2b -> ALOAD_1
610
611java/lang/Class.desiredAssertionStatus() 寄存器(指令):0xc7 -> IFNONNULL
612
613java/lang/Class.desiredAssertionStatus() 寄存器(指令):0x2a -> ALOAD_0
614
615java/lang/Class.desiredAssertionStatus() 寄存器(指令):0xb8 -> INVOKE_STATIC
616
617java/lang/Class.desiredAssertionStatus0() 寄存器(指令):0xfe -> INVOKE_NATIVE
618
619java/lang/Class.desiredAssertionStatus0() 寄存器(指令):0xac -> IRETURN
620
621java/lang/Class.desiredAssertionStatus() 寄存器(指令):0xac -> IRETURN
622
623java/lang/Throwable.<clinit>() 寄存器(指令):0x9a -> IFNE
624
625java/lang/Throwable.<clinit>() 寄存器(指令):0x04 -> ICONST_1
626
627java/lang/Throwable.<clinit>() 寄存器(指令):0xa7 -> GOTO
628
629java/lang/Throwable.<clinit>() 寄存器(指令):0xb3 -> PUT_STATIC
630
631java/lang/Throwable.<clinit>() 寄存器(指令):0x03 -> ICONST_0
632
633java/lang/Throwable.<clinit>() 寄存器(指令):0xbd -> ANEW_ARRAY
634
635java/lang/Throwable.<clinit>() 寄存器(指令):0xb3 -> PUT_STATIC
636
637java/lang/Throwable.<clinit>() 寄存器(指令):0xbb -> NEW
638
639java/lang/Throwable.<clinit>() 寄存器(指令):0x59 -> DUP
640
641java/lang/Throwable.<clinit>() 寄存器(指令):0x03 -> ICONST_0
642
643java/lang/Throwable.<clinit>() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
644
645java/util/ArrayList.<init>() 寄存器(指令):0x2a -> ALOAD_0
646
647java/util/ArrayList.<init>() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
648
649java/util/AbstractList.<init>() 寄存器(指令):0x2a -> ALOAD_0
650
651java/util/AbstractList.<init>() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
652
653java/util/AbstractCollection.<init>() 寄存器(指令):0x2a -> ALOAD_0
654
655java/util/AbstractCollection.<init>() 寄存器(指令):0xb7 -> INVOKE_SPECIAL
656
657java/lang/Object.<init>() 寄存器(指令):0xb1 -> RETURN
658
659java/util/AbstractCollection.<init>() 寄存器(指令):0xb1 -> RETURN
660
661java/util/AbstractList.<init>() 寄存器(指令):0x2a -> ALOAD_0
662
663java/util/AbstractList.<init>() 寄存器(指令):0x03 -> ICONST_0
664
665java/util/AbstractList.<init>() 寄存器(指令):0xb5 -> PUT_FIELD
666
667java/util/AbstractList.<init>() 寄存器(指令):0xb1 -> RETURN
668
669java/util/ArrayList.<init>() 寄存器(指令):0x1b -> ILOAD_1
670
671java/util/ArrayList.<init>() 寄存器(指令):0x9e -> IFLE
672
673java/util/ArrayList.<init>() 寄存器(指令):0x1b -> ILOAD_1
674
675java/util/ArrayList.<init>() 寄存器(指令):0x9a -> IFNE
676
677java/util/ArrayList.<init>() 寄存器(指令):0x2a -> ALOAD_0
678
679java/util/ArrayList.<init>() 寄存器(指令):0xb2 -> GET_STATIC
680
681java/util/ArrayList.<init>() 寄存器(指令):0xb5 -> PUT_FIELD
682
683java/util/ArrayList.<init>() 寄存器(指令):0xa7 -> GOTO
684
685java/util/ArrayList.<init>() 寄存器(指令):0xb1 -> RETURN
686
687java/lang/Throwable.<clinit>() 寄存器(指令):0xb8 -> INVOKE_STATIC
688
689java/util/Collections.unmodifiableList() 寄存器(指令):0x2a -> ALOAD_0
690
691java/util/Collections.unmodifiableList() 寄存器(指令):0xc1 -> INSTANCE_OF
820
821java/lang/Throwable.fillInStackTrace() 寄存器(指令):0xb0 -> ARETURN
822
823java/lang/Throwable.<init>() 寄存器(指令):0x57 -> POP
824
825java/lang/Throwable.<init>() 寄存器(指令):0x2a -> ALOAD_0
826
827java/lang/Throwable.<init>() 寄存器(指令):0x2b -> ALOAD_1
828
829java/lang/Throwable.<init>() 寄存器(指令):0xb5 -> PUT_FIELD
830
831java/lang/Throwable.<init>() 寄存器(指令):0xb1 -> RETURN
832
833java/lang/Exception.<init>() 寄存器(指令):0xb1 -> RETURN
834
835java/lang/RuntimeException.<init>() 寄存器(指令):0xb1 -> RETURN
836
837org/itstack/demo/test/HelloWorld.main() 寄存器(指令):0xbf -> ATHROW
838
839java.lang.RuntimeException:自定义异常
840
841org.itstack.demo.test.HelloWorld.main(HelloWorld.java:9)
842
843
844
845Process finished with exit code 0