龙空技术网

如何用Java实现JVM中的类和对象?

月亮跌进深海里 41

前言:

今天各位老铁们对“java frame类”大概比较看重,朋友们都需要知道一些“java frame类”的相关内容。那么小编也在网络上汇集了一些关于“java frame类””的相关文章,希望我们能喜欢,你们一起来学习一下吧!

案例介绍

本案例通过java代码实现jvm规范中指令集和解释器,完成后就可以开始执行1到100的加和计算。

Java虚拟机顾名思义,就是一台虚拟的机器,而字节码(bytecode)就是运行在这台虚拟机器上的机器码。我们已经知道,每一个类或者接口都会被Java编译器编译成一个class文件,类或接口的方法信息就放在class文件的method_info结构中。如果方法不是抽象的,也不是本地方法,方法的Java代码就会被编译器编译成字节码(即使方法是空的,编译器也会生成一条return语句),存在method_info结构的Code属性中。

环境准备jdk 1.8.0IntelliJ IDEA Community Edition 2018.3.1 x64配置信息调试配置配置位置:Run/Debug Configurations -> program arguments配置内容:-Xjre “C:\Program Files\Java\jdk1.8.0_161\jre” E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-06\target\test-classes\org\itstack\demo\test\HelloWorld代码示例

itstack-demo-jvm-06├── pom.xml└── src    └── main    │    └── java    │        └── org.itstack.demo.jvm	│             ├── classfile    │             │   ├── attributes   {BootstrapMethods/Code/ConstantValue...}    │             │   ├── constantpool {CONSTANT_TAG_CLASS/CONSTANT_TAG_FIELDREF/CONSTANT_TAG_METHODREF...}    │             │   ├── ClassFile.java    │             │   ├── ClassReader.java    │             │   └── MemberInfo.java	    │             ├── classpath    │             │   ├── impl    │             │   │   ├── CompositeEntry.java    │             │   │   ├── DirEntry.java     │             │   │   ├── WildcardEntry.java     │             │   │   └── ZipEntry.java        │             │   ├── Classpath.java    │             │   └── Entry.java       │             ├── classpath    │             │   ├── base    │             │   ├── comparisons    │             │   ├── constants    │             │   ├── control    │             │   ├── conversions    │             │   ├── extended    │             │   ├── loads    │             │   ├── math    │             │   │   ├── add    │             │   │   ├── and    │             │   │   ├── div    │             │   │   ├── iinc    │             │   │   ├── mul    │             │   │   ├── neg    │             │   │   ├── or    │             │   │   ├── rem    │             │   │   ├── sh    │             │   │   ├── sub    │             │   │   └── xor    │             │   ├── stack    │             │   ├── store    │             │   └── Factory	    │             ├── rtda    │             │   ├── heap    │             │   │   ├── constantpool    │             │   │   ├── methodarea    │             │   │   │   ├── Class.java 	    │             │   │   │   ├── ClassMember.java	    │             │   │   │   ├── Field.java	    │             │   │   │   ├── Method.java	    │             │   │   │   ├── Object.java	    │             │   │   │   └── Slots.java		    │             │   │   └── ClassLoader.java	    │             │   ├── Frame.java    │             │   ├── JvmStack.java    │             │   ├── LocalVars.java    │             │   ├── OperandStack.java    │             │   ├── Slot.java	    │             │   └── Thread.java    │             ├── Cmd.java    │             ├── Interpret.java	    │             └── Main.java    └── test         └── java             └── org.itstack.demo.test                 └── HelloWorld.java

Class.java

public class Class {    public int accessFlags;    public String name;    public String superClassName;    public String[] interfaceNames;    public RunTimeConstantPool runTimeConstantPool;    public Field[] fields;    public Method[] methods;    public ClassLoader loader;    public Class superClass;    public Class[] interfaces;    public int instanceSlotCount;    public int staticSlotCount;    public Slots staticVars;    public Class(ClassFile classFile) {        this.accessFlags = classFile.accessFlags();        this.name = classFile.className();        this.superClassName = classFile.superClassName();        this.interfaceNames = classFile.interfaceNames();        this.runTimeConstantPool = new RunTimeConstantPool(this, classFile.constantPool());        this.fields = new Field().newFields(this, classFile.fields());        this.methods = new Method().newMethods(this, classFile.methods());    }    public boolean isPublic() {        return 0 != (this.accessFlags & AccessFlags.ACC_PUBLIC);    }    public boolean isFinal() {        return 0 != (this.accessFlags & AccessFlags.ACC_FINAL);    }    public boolean isSuper() {        return 0 != (this.accessFlags & AccessFlags.ACC_SUPER);    }    public boolean isInterface() {        return 0 != (this.accessFlags & AccessFlags.ACC_INTERFACE);    }    public boolean isAbstract() {        return 0 != (this.accessFlags & AccessFlags.ACC_ABSTRACT);    }    public boolean isSynthetic() {        return 0 != (this.accessFlags & AccessFlags.ACC_SYNTHETIC);    }    public boolean isAnnotation() {        return 0 != (this.accessFlags & AccessFlags.ACC_ANNOTATION);    }    public boolean isEnum() {        return 0 != (this.accessFlags & AccessFlags.ACC_ENUM);    }    public RunTimeConstantPool constantPool() {        return this.runTimeConstantPool;    }    public Slots staticVars() {        return this.staticVars;    }    public boolean isAccessibleTo(Class other) {        return this.isPublic() || this.getPackageName().equals(other.getPackageName());    }    public String getPackageName() {        int i = this.name.lastIndexOf("/");        if (i >= 0) return this.name;        return "";    }    public Method getMainMethod() {        return this.getStaticMethod("main", "([Ljava/lang/String;)V");    }    private Method getStaticMethod(String name, String descriptor) {        for (Method method : this.methods) {            if (method.name.equals(name) && method.descriptor.equals(descriptor)) {                return method;            }        }        return null;    }    public Object newObject() {        return new Object(this);    }    public boolean isAssignableFrom(Class other) {        if (this == other) return true;        if (!other.isInterface()) {            return this.isSubClassOf(other);        } else {            return this.isImplements(other);        }    }    public boolean isSubClassOf(Class other) {        for (Class c = this.superClass; c != null; c = c.superClass) {            if (c == other) {                return true;            }        }        return false;    }    private boolean isImplements(Class other) {        for (Class c = this; c != null; c = c.superClass) {            for (Class clazz : c.interfaces) {                if (clazz == other || clazz.isSubInterfaceOf(other)) {                    return true;                }            }        }        return false;    }    public boolean isSubInterfaceOf(Class iface) {        for (Class superInterface : this.interfaces) {            if (superInterface == iface || superInterface.isSubInterfaceOf(iface)) {                return true;            }        }        return false;    }}

ClassMember.java

public class ClassMember {    public int accessFlags;    public String name;    public String descriptor;    public Class clazz;    public void copyMemberInfo(MemberInfo memberInfo) {        this.accessFlags = memberInfo.accessFlags();        this.name = memberInfo.name();        this.descriptor = memberInfo.descriptor();    }    public boolean isPublic() {        return 0 != (this.accessFlags & AccessFlags.ACC_PUBLIC);    }    public boolean isPrivate() {        return 0 != (this.accessFlags & AccessFlags.ACC_PRIVATE);    }    public boolean isProtected() {        return 0 != (this.accessFlags & AccessFlags.ACC_PROTECTED);    }    public boolean isStatic() {        return 0 != (this.accessFlags & AccessFlags.ACC_STATIC);    }    public boolean isFinal() {        return 0 != (this.accessFlags & AccessFlags.ACC_FINAL);    }    public boolean isSynthetic() {        return 0 != (this.accessFlags & AccessFlags.ACC_SYNTHETIC);    }    public String name() {        return this.name;    }    public String descriptor() {        return this.descriptor;    }    public Class clazz() {        return this.clazz;    }    public boolean isAccessibleTo(Class d) {        if (this.isPublic()) {            return true;        }        Class c = this.clazz;        if (this.isProtected()) {            return d == c || c.getPackageName().equals(d.getPackageName());        }        if (!this.isPrivate()) {            return c.getPackageName().equals(d.getPackageName());        }        return d == c;    }}

Field.java

package org.itstack.demo.jvm.rtda.heap.methodarea;import org.itstack.demo.jvm.classfile.MemberInfo;import org.itstack.demo.jvm.classfile.attributes.impl.ConstantValueAttribute;import org.itstack.demo.jvm.rtda.heap.constantpool.AccessFlags;public class Field extends ClassMember {    public int constValueIndex;    public int slotId;    public Field[] newFields(Class clazz, MemberInfo[] cfFields) {        Field[] fields = new Field[cfFields.length];        for (int i = 0; i < cfFields.length; i++) {            fields[i] = new Field();            fields[i].clazz = clazz;            fields[i].copyMemberInfo(cfFields[i]);            fields[i].copyAttributes(cfFields[i]);        }        return fields;    }    public void copyAttributes(MemberInfo cfField) {        ConstantValueAttribute valAttr = cfField.ConstantValueAttribute();        if (null != valAttr) {            this.constValueIndex = valAttr.constantValueIdx();        }    }    public boolean isVolatile() {        return 0 != (this.accessFlags & AccessFlags.ACC_VOLATILE);    }    public boolean isTransient() {        return 0 != (this.accessFlags & AccessFlags.ACC_TRANSIENT);    }    public boolean isEnum() {        return 0 != (this.accessFlags & AccessFlags.ACC_ENUM);    }    public int constValueIndex() {        return this.constValueIndex;    }    public int slotId() {        return this.slotId;    }    public boolean isLongOrDouble() {        return this.descriptor.equals("J") || this.descriptor.equals("D");    }}

Method.java

package org.itstack.demo.jvm.rtda.heap.methodarea;import org.itstack.demo.jvm.classfile.MemberInfo;import org.itstack.demo.jvm.classfile.attributes.impl.CodeAttribute;import org.itstack.demo.jvm.rtda.heap.constantpool.AccessFlags;public class Method extends ClassMember {    public int maxStack;    public int maxLocals;    public byte[] code;    public Method[] newMethods(Class clazz, MemberInfo[] cfMethods) {        Method[] methods = new Method[cfMethods.length];        for (int i = 0; i < cfMethods.length; i++) {            methods[i] = new Method();            methods[i].clazz = clazz;            methods[i].copyMemberInfo(cfMethods[i]);            methods[i].copyAttributes(cfMethods[i]);        }        return methods;    }    public void copyAttributes(MemberInfo cfMethod) {        CodeAttribute codeAttr = cfMethod.codeAttribute();        if (null != codeAttr) {            this.maxStack = codeAttr.maxStack();            this.maxLocals = codeAttr.maxLocals();            this.code = codeAttr.data();        }    }    public boolean isSynchronized() {        return 0 != (this.accessFlags & AccessFlags.ACC_SYNCHRONIZED);    }    public boolean isBridge() {        return 0 != (this.accessFlags & AccessFlags.ACC_BRIDGE);    }    public boolean isVarargs() {        return 0 != (this.accessFlags & AccessFlags.ACC_VARARGS);    }    public boolean isNative() {        return 0 != (this.accessFlags & AccessFlags.ACC_NATIVE);    }    public boolean isAbstract() {        return 0 != (this.accessFlags & AccessFlags.ACC_ABSTRACT);    }    public boolean isStrict() {        return 0 != (this.accessFlags & AccessFlags.ACC_STRICT);    }    public int maxStack() {        return this.maxStack;    }    public int maxLocals() {        return this.maxLocals;    }    public byte[] code() {        return this.code;    }}

Object.java

package org.itstack.demo.jvm.rtda.heap.methodarea;public class Object {    Class clazz;    Slots fields;    public Object(Class clazz){        this.clazz = clazz;        this.fields = new Slots(clazz.instanceSlotCount);    }    public Class clazz(){        return this.clazz;    }    public Slots fields(){        return this.fields;    }    public boolean isInstanceOf(Class clazz){        return clazz.isAssignableFrom(this.clazz);    }}

Slots.java

package org.itstack.demo.jvm.rtda.heap.methodarea;import org.itstack.demo.jvm.rtda.Slot;public class Slots {    private Slot[] slots;    public Slots(int slotCount) {        if (slotCount > 0) {            slots = new Slot[slotCount];            for (int i = 0; i < slotCount; i++) {                slots[i] = new Slot();            }        }    }    public void setInt(int idx, int val) {        this.slots[idx].num = val;    }    public int getInt(int idx) {        return this.slots[idx].num;    }    public void setFloat(int idx, float val) {        this.slots[idx].num = (int) val;    }    public float getFloat(int idx) {        return this.slots[idx].num;    }    public void setLong(int idx, long val) {        this.slots[idx].num = (int) val;        this.slots[idx + 1].num = (int) (val >> 32);    }    public long getLong(int idx) {        int low = this.slots[idx].num;        int high = this.slots[idx + 1].num;        return (long) high << 32 | (long) low;    }    public void setDouble(int idx, double val) {        this.setLong(idx, (long) val);    }    public Double getDouble(int idx) {        return (double) this.getLong(idx);    }    public void setRef(int idx, Object ref) {        this.slots[idx].ref = ref;    }    public Object getRef(int idx){        return this.slots[idx].ref;    }}
测试结果 {可以看到已经输出;5050}
"C:\Program Files\Java\jdk1.8.0_161\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.3.1\lib\idea_rt.jar=61887:D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.3.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_161\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\rt.jar;E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\classes;D:\Program Files (x86)\apache-maven-2.2.1\repository\com\beust\jcommander\1.72\jcommander-1.72.jar;D:\Program Files (x86)\apache-maven-2.2.1\repository\org\projectlombok\lombok\1.18.0\lombok-1.18.0.jar;D:\Program Files (x86)\apache-maven-2.2.1\repository\com\alibaba\fastjson\1.2.40\fastjson-1.2.40.jar" org.itstack.demo.jvm.Main -Xjre "C:\Program Files\Java\jdk1.8.0_161\jre" E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\test-classes\org\itstack\demo\test\HelloWorldclasspath:org.itstack.demo.jvm.classpath.Classpath@4bf558aa class:E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\test-classes\org\itstack\demo\test\HelloWorld args:null寄存器(指令):0x03 -> ICONST_0 => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]寄存器(指令):0x3c -> ISTORE_1 => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]寄存器(指令):0x04 -> ICONST_1 => 局部变量表:[{"num":0},{"num":0}] 操作数栈:[{"num":0},{"num":0}]寄存器(指令):0x3d -> ISTORE_2 => 局部变量表:[{"num":1},{"num":0}] 操作数栈:[{"num":1},{"num":0}]寄存器(指令):0x1c -> ILOAD_2 => 局部变量表:[{"num":1},{"num":0}] 操作数栈:[{"num":1},{"num":0}]寄存器(指令):0x10 -> BIPUSH => 局部变量表:[{"num":1},{"num":0}] 操作数栈:[{"num":1},{"num":0}]寄存器(指令):0xa3 -> IF_ICMPGT => 局部变量表:[{"num":1},{"num":100}] 操作数栈:[{"num":1},{"num":100}]寄存器(指令):0x1b -> ILOAD_1 => 局部变量表:[{"num":1},{"num":100}] 操作数栈:[{"num":1},{"num":100}]寄存器(指令):0x1c -> ILOAD_2 => 局部变量表:[{"num":0},{"num":100}] 操作数栈:[{"num":0},{"num":100}]... ...寄存器(指令):0x60 -> IADD => 局部变量表:[{"num":4950},{"num":100}] 操作数栈:[{"num":4950},{"num":100}]寄存器(指令):0x3c -> ISTORE_1 => 局部变量表:[{"num":5050},{"num":100}] 操作数栈:[{"num":5050},{"num":100}]寄存器(指令):0x84 -> IINC => 局部变量表:[{"num":5050},{"num":100}] 操作数栈:[{"num":5050},{"num":100}]寄存器(指令):0xa7 -> GOTO => 局部变量表:[{"num":5050},{"num":100}] 操作数栈:[{"num":5050},{"num":100}]寄存器(指令):0x1c -> ILOAD_2 => 局部变量表:[{"num":5050},{"num":100}] 操作数栈:[{"num":5050},{"num":100}]寄存器(指令):0x10 -> BIPUSH => 局部变量表:[{"num":101},{"num":100}] 操作数栈:[{"num":101},{"num":100}]寄存器(指令):0xa3 -> IF_ICMPGT => 局部变量表:[{"num":101},{"num":100}] 操作数栈:[{"num":101},{"num":100}]5050寄存器(指令):0xb1 -> RETURN => 局部变量表:[{"num":101},{"num":5050}] 操作数栈:[{"num":101},{"num":5050}]Exception in thread "main" java.lang.RuntimeException: jvm stack is empty!	at org.itstack.demo.jvm.rtda.JvmStack.pop(JvmStack.java:33)

今天的分享就到这了,我这里准备了一套java进阶方法笔记,学习资料面试题,电子书等免费笔记供大家学习.需要的小伙伴私信我回复"Java"即可领取免费资料.

java核心知识点

标签: #java frame类