小傅哥 | https://bugstack.cn
沉淀、分享、成长,专注于原创专题案例,以最易学习编程的方式分享知识,让自己和他人都能有所收获。目前已完成的专题有;Netty4.x实战专题案例、用Java实现JVM、基于JavaAgent的全链路监控、手写RPC框架、架构设计专题案例、源码分析等。
你用剑 、我用刀 ,好的代码都很烧,望你不吝出招!

一、案例介绍

本章主要介绍如何实现让虚拟机处理数组和字符串,在虚拟机功能增强后,我们可以执行数组类型计算和输出字符串。本章需要新增实现数组指令;newarray、anewarray、arraylength、aload、astore、multianewarray、ldc,同时需要需要开发字符串池方法等。

数组在Java虚拟机中是给比较特殊的概念,主要有以下原因;
首先,数组类和普通的类是不同的。普通的类从class文件中加载,但是数组类由Java虚拟机在运行时生成。数组的类名是左括号([)+数组元素的类型描述符;数组的类型描述符就是类名本身。例如,int[]的类名是[I,int的类名是[[I,Object[]的类名是[Ljava/lang/Object;,String的类名是[[java/lang/String;,等等。
其次,创建数组的方式和创建普通对象的方式不同。普通对象new指令创建,然后由构造函数初始化。基本类型数组由newarray指令创建;引用类型数组由anewarray指令创建;另外还有一个专门的mulitianewarray指令用于创建多维数组。
最后,很显然,数组和普通对象存在的数据也是不同的。普通对象中存放的是实例变量,通过putfield和getfield指令存取。数组对象中存放的则是数组元素,通过aload和astore系列指令按索引存取。其中可以是a、b、c、d、f、i、l或者s,分别用于存取引用、byte、char、double、float、int、long或者shore类型的数组。另外,还有一个arraylength指令,用于获取数组长度。

二、环境准备

  1. jdk 1.8.0
  2. IntelliJ IDEA Community Edition 2018.3.1 x64

三、配置信息

  1. 调试配置
11. 配置位置:Run/Debug Configurations -> program arguments12. 配置内容(执行数组计算):-Xjre "C:Program FilesJavajdk1.8.0_161jre" E:itstackgitistack-demoitstack-demo-jvmitstack-demo-jvm-08targettest-classesorgitstackdemotestBubbleSortTest13. 配置内容(字符串的输出):-Xjre "C:Program FilesJavajdk1.8.0_161jre" E:itstackgitistack-demoitstack-demo-jvmitstack-demo-jvm-08targettest-classesorgitstackdemotestHelloWorld -verbose true -args 你好,java版虚拟机v1.0,欢迎你的到来。

四、代码示例

  1itstack-demo-jvm-0823├── pom.xml45└── src67    └── main89    │    └── java1011    │        └── org.itstack.demo.jvm1213    │             ├── classfile1415    │             │   ├── attributes   {BootstrapMethods/Code/ConstantValue...}1617    │             │   ├── constantpool {CONSTANT_TAG_CLASS/CONSTANT_TAG_FIELDREF/CONSTANT_TAG_METHODREF...}1819    │             │   ├── ClassFile.java2021    │             │   ├── ClassReader.java2223    │             │   └── MemberInfo.java   2425    │             ├── classpath2627    │             │   ├── impl2829    │             │   │   ├── CompositeEntry.java3031    │             │   │   ├── DirEntry.java 3233    │             │   │   ├── WildcardEntry.java 3435    │             │   │   └── ZipEntry.java    3637    │             │   ├── Classpath.java3839    │             │   └── Entry.java   4041    │             ├── classpath4243    │             │   ├── base4445    │             │   │   ├── BytecodeReader.java4647    │             │   │   ├── ClassInitLogic.java4849    │             │   │   ├── Instruction.java5051    │             │   │   ├── InstructionBranch.java5253    │             │   │   ├── InstructionIndex8.java5455    │             │   │   ├── InstructionIndex16.java5657    │             │   │   ├── InstructionNoOperands.java    5859    │             │   │   └── MethodInvokeLogic.java6061    │             │   ├── comparisons6263    │             │   ├── constants6465    │             │   ├── control6667    │             │   ├── conversions6869    │             │   ├── extended7071    │             │   ├── loads7273    │             │   ├── math7475    │             │   ├── references7677    │             │   │   ├── ANEW_ARRAY.java7879    │             │   │   ├── ARRAY_LENGTH.java8081    │             │   │   ├── CHECK_CAST.java8283    │             │   │   ├── GET_FIELD.java8485    │             │   │   ├── GET_STATIC.java8687    │             │   │   ├── INSTANCE_OF.java8889    │             │   │   ├── INVOKE_INTERFACE.java9091    │             │   │   ├── INVOKE_SPECIAL.java9293    │             │   │   ├── INVOKE_STATIC.java9495    │             │   │   ├── INVOKE_VIRTUAL.java9697    │             │   │   ├── MULTI_ANEW_ARRAY.java9899    │             │   │   ├── NEW.java
100
101    │             │   │   ├── NEW_ARRAY.java
102
103    │             │   │   ├── PUT_FIELD.java
104
105    │             │   │   └── PUT_STATIC.java
106
107    │             │   ├── stack
108
109    │             │   ├── store
110
111    │             │   │   └── xastore
112
113    │             │   │       ├── AASTORE.java
114
115    │             │   │       ├── BASTORE.java
116
117    │             │   │       ├── CASTORE.java
118
119    │             │   │       ├── DASTORE.java
120
121    │             │   │       ├── FASTORE.java
122
123    │             │   │       ├── IASTORE.java
124
125    │             │   │       ├── LASTORE.java
126
127    │             │   │       └── SASTORE.java
128
129    │             │   └── Factory
130
131    │             ├── rtda
132
133    │             │   ├── heap
134
135    │             │   │   ├── constantpool
136
137    │             │   │   ├── methodarea
138
139    │             │   │   │   ├── Class.java
140
141    │             │   │   │   ├── ClassMember.java
142
143    │             │   │   │   ├── Field.java
144
145    │             │   │   │   ├── Method.java
146
147    │             │   │   │   ├── MethodDescriptor.java
148
149    │             │   │   │   ├── MethodDescriptorParser.java
150
151    │             │   │   │   ├── MethodLookup.java
152
153    │             │   │   │   ├── Object.java
154
155    │             │   │   │   ├── Slots.java
156
157    │             │   │   │   └── StringPool.java
158
159    │             │   │   └── ClassLoader.java
160
161    │             │   ├── Frame.java
162
163    │             │   ├── JvmStack.java
164
165    │             │   ├── LocalVars.java
166
167    │             │   ├── OperandStack.java
168
169    │             │   ├── Slot.java
170
171    │             │   └── Thread.java
172
173    │             ├── Cmd.java
174
175    │             ├── Interpret.java
176
177    │             └── Main.java
178
179    └── test
180
181         └── java
182
183             └── org.itstack.demo.test
184
185                 ├── BubbleSortTest.java
186
187                 └── HelloWorld.java

代码片段

ANEW_ARRAY.java

 1package org.itstack.demo.jvm.instructions.references;2345import org.itstack.demo.jvm.instructions.base.InstructionIndex16;67import org.itstack.demo.jvm.rtda.Frame;89import org.itstack.demo.jvm.rtda.OperandStack;
10
11import org.itstack.demo.jvm.rtda.heap.constantpool.ClassRef;
12
13import org.itstack.demo.jvm.rtda.heap.constantpool.RunTimeConstantPool;
14
15import org.itstack.demo.jvm.rtda.heap.methodarea.Class;
16
17import org.itstack.demo.jvm.rtda.heap.methodarea.Object;
18
19
20
21/**
22
23 * https://bugstack.cn/
24
25 * create by fuzhengwei on 2019/4/29
26
27 * create new array of reference
28
29 */
30
31public class ANEW_ARRAY extends InstructionIndex16 {
32
33
34
35    @Override
36
37    public void execute(Frame frame) {
38
39
40
41        RunTimeConstantPool runTimeConstantPool = frame.method().clazz().constantPool();
42
43        ClassRef classRef = (ClassRef) runTimeConstantPool.getConstants(this.idx);
44
45        Class componentClass = classRef.resolvedClass();
46
47
48
49        OperandStack stack = frame.operandStack();
50
51        int count = stack.popInt();
52
53        if (count < 0) {
54
55            throw new NegativeArraySizeException();
56
57        }
58
59
60
61        Class arrClass = componentClass.arrayClass();
62
63        Object arr = arrClass.newArray(count);
64
65        stack.pushRef(arr);
66
67
68
69    }
70
71
72
73}

ARRAY_LENGTH.java

 1package org.itstack.demo.jvm.instructions.references;2345import org.itstack.demo.jvm.instructions.base.InstructionNoOperands;67import org.itstack.demo.jvm.rtda.Frame;89import org.itstack.demo.jvm.rtda.OperandStack;
10
11import org.itstack.demo.jvm.rtda.heap.methodarea.Object;
12
13
14
15/**
16
17 * https://bugstack.cn/
18
19 * create by fuzhengwei on 2019/4/29
20
21 * get length of array
22
23 */
24
25public class ARRAY_LENGTH extends InstructionNoOperands {
26
27
28
29    @Override
30
31    public void execute(Frame frame) {
32
33
34
35        OperandStack stack = frame.operandStack();
36
37        Object arrRef = stack.popRef();
38
39        if (null == arrRef){
40
41            throw new NullPointerException();
42
43        }
44
45
46
47        int arrLen = arrRef.arrayLength();
48
49        stack.pushInt(arrLen);
50
51    }
52
53
54
55}

NEW_ARRAY.java

  1package org.itstack.demo.jvm.instructions.references;2345import org.itstack.demo.jvm.instructions.base.BytecodeReader;67import org.itstack.demo.jvm.instructions.base.Instruction;89import org.itstack.demo.jvm.rtda.Frame;1011import org.itstack.demo.jvm.rtda.OperandStack;1213import org.itstack.demo.jvm.rtda.heap.ClassLoader;1415import org.itstack.demo.jvm.rtda.heap.methodarea.Class;1617import org.itstack.demo.jvm.rtda.heap.methodarea.Object;18192021/**2223 * https://bugstack.cn/2425 * create by fuzhengwei on 2019/4/292627 */2829public class NEW_ARRAY implements Instruction {30313233    private byte atype;34353637    @Override3839    public void fetchOperands(BytecodeReader reader) {4041        this.atype = reader.readByte();4243    }44454647    @Override4849    public void execute(Frame frame) {5051        OperandStack stack = frame.operandStack();5253        int count = stack.popInt();5455        if (count < 0) {5657            throw new NegativeArraySizeException();5859        }60616263        ClassLoader classLoader = frame.method().clazz().loader();6465        Class arrClass = getPrimitiveArrayClass(classLoader, this.atype);6667        Object arr = arrClass.newArray(count);6869        stack.pushRef(arr);70717273    }74757677    private Class getPrimitiveArrayClass(ClassLoader loader, byte atype){7879        switch (atype) {8081            case ArrayType.AT_BOOLEAN:8283                return loader.loadClass("[Z");8485            case ArrayType.AT_BYTE:8687                return loader.loadClass("[B");8889            case ArrayType.AT_CHAR:9091                return loader.loadClass("[C");9293            case ArrayType.AT_SHORT:9495                return loader.loadClass("[S");9697            case ArrayType.AT_INT:9899                return loader.loadClass("[I");
100
101            case ArrayType.AT_LONG:
102
103                return loader.loadClass("[J");
104
105            case ArrayType.AT_FLOAT:
106
107                return loader.loadClass("[F");
108
109            case ArrayType.AT_DOUBLE:
110
111                return loader.loadClass("[D");
112
113            default:
114
115                throw new RuntimeException("Invalid atype!");
116
117        }
118
119    }
120
121
122
123    static class ArrayType {
124
125        static final byte AT_BOOLEAN = 4;
126
127        static final byte AT_CHAR = 5;
128
129        static final byte AT_FLOAT = 6;
130
131        static final byte AT_DOUBLE = 7;
132
133        static final byte AT_BYTE = 8;
134
135        static final byte AT_SHORT = 9;
136
137        static final byte AT_INT = 10;
138
139        static final byte AT_LONG = 11;
140
141    }
142
143
144
145}

IASTORE.java

 1package org.itstack.demo.jvm.instructions.stores.xastore;2345import org.itstack.demo.jvm.instructions.base.InstructionNoOperands;67import org.itstack.demo.jvm.rtda.Frame;89import org.itstack.demo.jvm.rtda.OperandStack;
10
11import org.itstack.demo.jvm.rtda.heap.methodarea.Object;
12
13
14
15/**
16
17 * https://bugstack.cn/
18
19 * create by fuzhengwei on 2019/4/29
20
21 */
22
23public class IASTORE extends InstructionNoOperands {
24
25
26
27    @Override
28
29    public void execute(Frame frame) {
30
31        OperandStack stack = frame.operandStack();
32
33        int val = stack.popInt();
34
35        int idx = stack.popInt();
36
37        Object arrRef = stack.popRef();
38
39
40
41        checkNotNull(arrRef);
42
43        int[] ints = arrRef.ints();
44
45        checkIndex(ints.length, idx);
46
47        ints[idx] = val;
48
49
50
51    }
52
53
54
55}

StringPool.java

 1package org.itstack.demo.jvm.rtda.heap.methodarea;2345import org.itstack.demo.jvm.rtda.heap.ClassLoader;6789import java.util.HashMap;
10
11import java.util.Map;
12
13
14
15/**
16
17 * https://bugstack.cn/
18
19 * create by fuzhengwei on 2019/4/29
20
21 */
22
23public class StringPool {
24
25
26
27    private static Map<String, Object> internedStrs = new HashMap<>();
28
29
30
31    public static Object jString(ClassLoader loader, String goStr) {
32
33        Object internedStr = internedStrs.get(goStr);
34
35        if (null != internedStr) return internedStr;
36
37
38
39        char[] chars = goStr.toCharArray();
40
41        Object jChars = new Object(loader.loadClass("[C"), chars);
42
43
44
45        Object jStr = loader.loadClass("java/lang/String").newObject();
46
47        jStr.setRefVal("value", "[C", jChars);
48
49
50
51        internedStrs.put(goStr, jStr);
52
53        return jStr;
54
55    }
56
57
58
59    public static String goString(Object jStr) {
60
61        Object charArr = jStr.getRefVar("value", "[C");
62
63        return new String(charArr.chars());
64
65    }
66
67
68
69}

Interpret.java

  1package org.itstack.demo.jvm;2345import com.alibaba.fastjson.JSON;67import org.itstack.demo.jvm.instructions.Factory;89import org.itstack.demo.jvm.instructions.base.BytecodeReader;1011import org.itstack.demo.jvm.instructions.base.Instruction;1213import org.itstack.demo.jvm.rtda.Frame;1415import org.itstack.demo.jvm.rtda.Thread;1617import org.itstack.demo.jvm.rtda.heap.ClassLoader;1819import org.itstack.demo.jvm.rtda.heap.methodarea.*;2021import org.itstack.demo.jvm.rtda.heap.methodarea.Class;2223import org.itstack.demo.jvm.rtda.heap.methodarea.Object;242526272829//指令集解释器3031class Interpret {32333435    Interpret(Method method, boolean logInst, String args) {3637        Thread thread = new Thread();3839        Frame frame = thread.newFrame(method);4041        thread.pushFrame(frame);42434445        if (null != args){4647            Object jArgs = createArgsArray(method.clazz().loader(), args.split(" "));4849            frame.localVars().setRef(0, jArgs);5051        }52535455        loop(thread, logInst);5657    }58596061    private Object createArgsArray(ClassLoader loader, String[] args) {6263        Class stringClass = loader.loadClass("java/lang/String");6465        Object argsArr = stringClass.arrayClass().newArray(args.length);6667        Object[] jArgs = argsArr.refs();6869        for (int i = 0; i < jArgs.length; i++) {7071            jArgs[i] = StringPool.jString(loader, args[i]);7273        }7475        return argsArr;7677    }78798081    private void loop(Thread thread, boolean logInst) {8283        BytecodeReader reader = new BytecodeReader();8485        while (true) {8687            Frame frame = thread.currentFrame();8889            int pc = frame.nextPC();9091            thread.setPC(pc);92939495            reader.reset(frame.method().code, pc);9697            byte opcode = reader.readByte();9899            Instruction inst = Factory.newInstruction(opcode);
100
101            if (null == inst) {
102
103                System.out.println("Unsupported opcode " + byteToHexString(new byte[]{opcode}));
104
105                break;
106
107            }
108
109            inst.fetchOperands(reader);
110
111            frame.setNextPC(reader.pc());
112
113
114
115            if (logInst) {
116
117                logInstruction(frame, inst, opcode);
118
119            }
120
121
122
123            //exec
124
125            inst.execute(frame);
126
127
128
129            if (thread.isStackEmpty()) {
130
131                break;
132
133            }
134
135        }
136
137    }
138
139
140
141    private static void logInstruction(Frame frame, Instruction inst, byte opcode) {
142
143        Method method = frame.method();
144
145        String className = method.clazz().name();
146
147        String methodName = method.name();
148
149        String outStr = (className + "." + methodName + "() t") +
150
151                "寄存器(指令):" + byteToHexString(new byte[]{opcode}) + " -> " + inst.getClass().getSimpleName() + " => 局部变量表:" + JSON.toJSONString(frame.operandStack().getSlots()) + " 操作数栈:" + JSON.toJSONString(frame.operandStack().getSlots());
152
153        System.out.println(outStr);
154
155    }
156
157
158
159    private static String byteToHexString(byte[] codes) {
160
161        StringBuilder sb = new StringBuilder();
162
163        sb.append("0x");
164
165        for (byte b : codes) {
166
167            int value = b & 0xFF;
168
169            String strHex = Integer.toHexString(value);
170
171            if (strHex.length() < 2) {
172
173                strHex = "0" + strHex;
174
175            }
176
177            sb.append(strHex);
178
179        }
180
181        return sb.toString();
182
183    }
184
185
186
187}

BubbleSortTest.java

 1package org.itstack.demo.test;2345/**67 * -Xjre "C:Program FilesJavajdk1.8.0_161jre" E:itstackgitistack-demoitstack-demo-jvmitstack-demo-jvm-08targettest-classesorgitstackdemotestBubbleSortTest -verbose true89 */
10
11public class BubbleSortTest {
12
13
14
15    public static void main(String[] args) {
16
17        int[] arr = {
18
19            22, 84, 77, 11, 95,  9, 78, 56,
20
21            36, 97, 65, 36, 10, 24 ,92, 48
22
23        };
24
25
26
27        //printArray(arr);
28
29        bubbleSort(arr);
30
31        //System.out.println(123456789);
32
33        printArray(arr);
34
35    }
36
37
38
39    private static void bubbleSort(int[] arr) {
40
41        boolean swapped = true;
42
43        int j = 0;
44
45        int tmp;
46
47        while (swapped) {
48
49            swapped = false;
50
51            j++;
52
53            for (int i = 0; i < arr.length - j; i++) {
54
55                if (arr[i] > arr[i + 1]) {
56
57                    tmp = arr[i];
58
59                    arr[i] = arr[i + 1];
60
61                    arr[i + 1] = tmp;
62
63                    swapped = true;
64
65                }
66
67            }
68
69        }
70
71    }
72
73
74
75    private static void printArray(int[] arr) {
76
77        for (int i : arr) {
78
79            System.out.println(i);
80
81        }
82
83    }
84
85
86
87}

HelloWorld.java

 1package org.itstack.demo.test;2345/**67 * -Xjre "C:Program FilesJavajdk1.8.0_161jre" E:itstackgitistack-demoitstack-demo-jvmitstack-demo-jvm-08targettest-classesorgitstackdemotestHelloWorld -verbose true -args 你好,java版虚拟机v1.0,欢迎你的到来。89 */
10
11public class HelloWorld {
12
13
14
15    public static void main(String[] args) {
16
17        for (String str : args) {
18
19            System.out.println(str);
20
21        }
22
23    }
24
25
26
27}

五、测试结果

分为测试数组、输出字符串;

1. 测试结果一;执行数组

  1-Xjre "C:Program FilesJavajdk1.8.0_161jre" E:itstackgitistack-demoitstack-demo-jvmitstack-demo-jvm-08targettest-classesorgitstackdemotestBubbleSortTest -verbose true23org/itstack/demo/test/BubbleSortTest.main()     寄存器(指令):0x10 -> BIPUSH => 局部变量表:[{"num":0},{"num":0},{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0},{"num":0},{"num":0}]45org/itstack/demo/test/BubbleSortTest.main()     寄存器(指令):0xbc -> NEW_ARRAY => 局部变量表:[{"num":16},{"num":0},{"num":0},{"num":0}] 操作数栈:[{"num":16},{"num":0},{"num":0},{"num":0}]67org/itstack/demo/test/BubbleSortTest.main()     寄存器(指令):0x59 -> DUP => 局部变量表:[{"num":16,"ref":{}},{"num":0},{"num":0},{"num":0}] 操作数栈:[{"num":16,"ref":{}},{"num":0},{"num":0},{"num":0}]867org/itstack/demo/test/BubbleSortTest.main()     寄存器(指令):0x10 -> BIPUSH => 局部变量表:[{"num":16,"ref":{}},{"num":16,"ref":{"$ref":"$[0].ref"}},{"num":7},{"num":78}] 操作数栈:[{"num":16,"ref":{}},{"num":16,"ref":{"$ref":"$[0].ref"}},{"num":7},{"num":78}]6869org/itstack/demo/test/BubbleSortTest.main()     寄存器(指令):0x4f -> IASTORE => 局部变量表:[{"num":16,"ref":{}},{"num":16,"ref":{"$ref":"$[0].ref"}},{"num":7},{"num":56}] 操作数栈:[{"num":16,"ref":{}},{"num":16,"ref":{"$ref":"$[0].ref"}},{"num":7},{"num":56}]
145... ...
146
147org/itstack/demo/test/BubbleSortTest.printArray()     寄存器(指令):0xb2 -> GET_STATIC => 局部变量表:[{"num":9},{"num":0}] 操作数栈:[{"num":9},{"num":0}]
148
149org/itstack/demo/test/BubbleSortTest.printArray()     寄存器(指令):0x15 -> ILOAD => 局部变量表:[{"num":9},{"num":0}] 操作数栈:[{"num":9},{"num":0}]
150
151org/itstack/demo/test/BubbleSortTest.printArray()     寄存器(指令):0xb6 -> INVOKE_VIRTUAL => 局部变量表:[{"num":9},{"num":9}] 操作数栈:[{"num":9},{"num":9}]
152
1539
209org/itstack/demo/test/BubbleSortTest.printArray()     寄存器(指令):0x84 -> IINC => 局部变量表:[{"num":97},{"num":97}] 操作数栈:[{"num":97},{"num":97}]
210
211org/itstack/demo/test/BubbleSortTest.printArray()     寄存器(指令):0xa7 -> GOTO => 局部变量表:[{"num":97},{"num":97}] 操作数栈:[{"num":97},{"num":97}]
212
213org/itstack/demo/test/BubbleSortTest.printArray()     寄存器(指令):0x1d -> ILOAD_3 => 局部变量表:[{"num":97},{"num":97}] 操作数栈:[{"num":97},{"num":97}]
214
215org/itstack/demo/test/BubbleSortTest.printArray()     寄存器(指令):0x1c -> ILOAD_2 => 局部变量表:[{"num":16},{"num":97}] 操作数栈:[{"num":16},{"num":97}]
216
217org/itstack/demo/test/BubbleSortTest.printArray()     寄存器(指令):0xa2 -> IF_ICMPGE => 局部变量表:[{"num":16},{"num":16}] 操作数栈:[{"num":16},{"num":16}]
218
219org/itstack/demo/test/BubbleSortTest.printArray()     寄存器(指令):0xb1 -> RETURN => 局部变量表:[{"num":16},{"num":16}] 操作数栈:[{"num":16},{"num":16}]
220
221org/itstack/demo/test/BubbleSortTest.main()     寄存器(指令):0xb1 -> RETURN => 局部变量表:[{"num":16,"ref":{}},{"num":16},{"num":15},{"num":48}] 操作数栈:[{"num":16,"ref":{}},{"num":16},{"num":15},{"num":48}]
222
223
224
225Process finished with exit code 0

2. 测试结果二;输出字符

 1org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x2a -> ALOAD_0 => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]23org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x4c -> ASTORE_1 => 局部变量表:[{"num":0,"ref":{}},{"num":0}] 操作数栈:[{"num":0,"ref":{}},{"num":0}]45org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x2b -> ALOAD_1 => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]67org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0xbe -> ARRAY_LENGTH => 局部变量表:[{"num":0,"ref":{}},{"num":0}] 操作数栈:[{"num":0,"ref":{}},{"num":0}]89org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x3d -> ISTORE_2 => 局部变量表:[{"num":1},{"num":0}] 操作数栈:[{"num":1},{"num":0}]
10
11org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x03 -> ICONST_0 => 局部变量表:[{"num":1},{"num":0}] 操作数栈:[{"num":1},{"num":0}]
12
13org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x3e -> ISTORE_3 => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]
14
15org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x1d -> ILOAD_3 => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]
16
17org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x1c -> ILOAD_2 => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]
18
19org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0xa2 -> IF_ICMPGE => 局部变量表:[{"num":0},{"num":1}] 操作数栈:[{"num":0},{"num":1}]
20
21org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x2b -> ALOAD_1 => 局部变量表:[{"num":0},{"num":1}] 操作数栈:[{"num":0},{"num":1}]
22
23org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x1d -> ILOAD_3 => 局部变量表:[{"num":0,"ref":{}},{"num":1}] 操作数栈:[{"num":0,"ref":{}},{"num":1}]
24
25org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x32 -> AALOAD => 局部变量表:[{"num":0,"ref":{}},{"num":0}] 操作数栈:[{"num":0,"ref":{}},{"num":0}]
26
27org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x3a -> ASTORE => 局部变量表:[{"num":0,"ref":{}},{"num":0}] 操作数栈:[{"num":0,"ref":{}},{"num":0}]
28
29org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0xb2 -> GET_STATIC => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]
30
31java/lang/Object.<clinit>()     寄存器(指令):0xb8 -> INVOKE_STATIC => 局部变量表:null 操作数栈:null
32
33java/lang/Object.<clinit>()     寄存器(指令):0xb1 -> RETURN => 局部变量表:null 操作数栈:null
34
35java/lang/System.<clinit>()     寄存器(指令):0xb8 -> INVOKE_STATIC => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
36
37java/lang/System.<clinit>()     寄存器(指令):0x01 -> ACONST_NULL => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
38
39java/lang/System.<clinit>()     寄存器(指令):0xb3 -> PUT_STATIC => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
40
41java/lang/System.<clinit>()     寄存器(指令):0x01 -> ACONST_NULL => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
42
43java/lang/System.<clinit>()     寄存器(指令):0xb3 -> PUT_STATIC => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
44
45java/lang/System.<clinit>()     寄存器(指令):0x01 -> ACONST_NULL => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
46
47java/lang/System.<clinit>()     寄存器(指令):0xb3 -> PUT_STATIC => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
48
49java/lang/System.<clinit>()     寄存器(指令):0x01 -> ACONST_NULL => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
50
51java/lang/System.<clinit>()     寄存器(指令):0xb3 -> PUT_STATIC => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
52
53java/lang/System.<clinit>()     寄存器(指令):0x01 -> ACONST_NULL => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
54
55java/lang/System.<clinit>()     寄存器(指令):0xb3 -> PUT_STATIC => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
56
57java/lang/System.<clinit>()     寄存器(指令):0xb1 -> RETURN => 局部变量表:[{"num":0}] 操作数栈:[{"num":0}]
58
59org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0xb2 -> GET_STATIC => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]
60
61org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x19 -> ALOAD => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]
62
63org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0xb6 -> INVOKE_VIRTUAL => 局部变量表:[{"num":0},{"num":0,"ref":{}}] 操作数栈:[{"num":0},{"num":0,"ref":{}}]
64
65
66
67你好,java版虚拟机v1.0,欢迎你的到来。
68
69
70
71org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x84 -> IINC => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]
72
73org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0xa7 -> GOTO => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]
74
75org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x1d -> ILOAD_3 => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]
76
77org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0x1c -> ILOAD_2 => 局部变量表:[{"num":1},{"num":0}] 操作数栈:[{"num":1},{"num":0}]
78
79org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0xa2 -> IF_ICMPGE => 局部变量表:[{"num":1},{"num":1}] 操作数栈:[{"num":1},{"num":1}]
80
81org/itstack/demo/test/HelloWorld.main()     寄存器(指令):0xb1 -> RETURN => 局部变量表:[{"num":1},{"num":1}] 操作数栈:[{"num":1},{"num":1}]

java字符串拆分成数组_用Java实现JVM第八章《数组和字符串》相关推荐

  1. java 输出流转换成输入流_在JAVA中如何将输出流转为输入流的类的实现

    问题背景 在实际应用中,我们会碰的一个功能的输出的字节流,是另一个功能输入字节流的情况.一般情况下,我们可以使用ByteArrayOutputStream和ByteArrayInputStream实现 ...

  2. python将字符串拆分成单词_将字符串拆分为单词和标点符号

    我正在尝试将字符串拆分为单词和标点符号,并将标点符号添加到拆分生成的列表中. 例如: >>> c = "help, me" >>> print ...

  3. java如果把字符串转成对象_为什么Java中的字符串对象是不可变的,有什么好处?...

    专注于Java领域优质技术号,欢迎关注 原创: 阿杜的世界 阅读本文大概需要 4分钟. 所谓不可变对象,是指一个对象在创建后,它的内部状态不会被改变的对象.这意味着当我们将一个不可变对象的引用赋值给某 ...

  4. Java 将字符串拆分成数组,实现字符串组合

    将字符串拆分成数组和实现字符串组合 不能使用语言的基本分割组合函数(如 Java 的 String.split, php 的 explode 和 implode) 1) 字符串拆分成字符串数组,如&q ...

  5. 把一个字符串分割成数组 php_PHP怎么将字符串拆分成数组

    在日常项目开发过程中,较长的字符串可能需要被拆分成数组形式,以便被展现或用于判断验证.那么将字符串拆分成数组,也很容易实现,我们可以直接通过PHP中的explode函数来进行拆分. 下面我们就通过简单 ...

  6. 【源码+图片素材】Java王者荣耀游戏开发_开发Java游戏项目【王者荣耀】1天搞定!!!腾讯游戏_Java课程设计_Java实战项目_Java初级项目

    王者荣耀是当下热门手游之一,小伙伴们是否想过如何制作一款属于自己的王者荣耀游戏呢? 本课程讲解了一个王者荣耀游戏的详细编写流程,即使你是刚入门Java的新手,只要你简单掌握了该游戏所需要的JavaSE ...

  7. UTF-8编码的字符串拆分成单字、获取UTF-8字符串的字符个数的代码及原理(c++实现)...

    一.字符编码简单介绍 1. ASCII码 在计算机内部,全部的信息终于都表示为一个二进制的字符串.每个二进制位(bit)有0和1两种状态,因此八个二进制位就能够组合出256种状态,这被称为一个字节(b ...

  8. c++ new 数组_用Java实现JVM第八章《数组和字符串》

    案例介绍 本章主要介绍如何实现让虚拟机处理数组和字符串,在虚拟机功能增强后,我们可以执行数组类型计算和输出字符串.本章需要新增实现数组指令:newarray.anewarray.arraylength ...

  9. java string改变的影响_为什么Java的string类要设成immutable(不可变的)

    最流行的Java面试题之一就是:什么是不可变对象(immutable object),不可变对象有什么好处,在什么情况下应该用,或者更具体一些,Java的String类为什么要设成immutable类 ...

最新文章

  1. linux sed错误sed: -e expression #1, unknown option to `s'解决办法
  2. 算法导论22章 基本图算法习题
  3. .Net Core小技巧 - Hosted Services + Quartz实现定时任务调度
  4. linux xorg.0.log,Red Hat无法登录,Cannot open log file /var/log/Xorg.0.log
  5. 函数局部变量和函数的参数在栈中的布局
  6. dubbo 自定义路由_Dubbo分层架构概述
  7. solr6.6+jetty+centos+mysql
  8. 【机器学习】监督学习--(回归)一元线性回归
  9. [下载]北京新版小学英语五年级上册mp3点读APP
  10. 异常来自 HRESULT:0x80070057 (E_INVALIDARG))
  11. Linux下安装NFS共享文件资源
  12. 天勤 数据结构 P80 T10
  13. 固件版本区别:alpha版、beta版、rc版、stable版
  14. CF1219G Harvester 题解
  15. Unity3D 协程
  16. mac安装linux时触控板不能用,macbookpro上装Deepin 20.2后wifi和触摸板不可用的解决
  17. Excel计算BOM物料数量的公式
  18. 大数据 - 大数据开发技术课程总结(未完)
  19. 曲面细分着色器---细分二维四边形
  20. SpringBoot+vue仿网易云音乐网站(三)- Springboot项目以及前端vue基础搭建

热门文章

  1. c语言遇到非法字符,98行的四则计算器.(支持括号)加入了非法字符的检测
  2. 微服务架构核心20讲 课程的学习笔记
  3. Java中的executeQuery,java连接数据库executeUpdate() 和executeQuery()
  4. 阿里二面:main 方法可以继承吗
  5. Java 17 将至,可能带来哪些新特性呢?
  6. 皮一皮:这就是我的开发水平...
  7. 合格的后端Coder都应该写好UT和Mock测试
  8. 让隔壁同事哇塞的IDEA主题!
  9. Linux 下 4 种实时监控日志文件的方法,总有一种适合你
  10. android仿微信的activity平滑水平切换动画,Android实现简单底部导航栏 Android仿微信滑动切换效果...