基础不牢,地动山摇,Java仍然是业界主流的开发语言之一,Java生态圈中有大量的组件框架,也包括大量大数据的组件如Hadoop等。我们想要更熟练透彻地掌握这些组件框架并更好地开发自己的程序,深入学习JVM的基础很有必要。本篇深入浅出来讲述Java字节码指令运行的过程,避免过度深入太多细节,让学习者可以对JVM解析字节码以及运行指令的过程有一个宏观的认识,对继续深入学习JVM相关知识有总体的把控。
Java:
public class ByteCodeT { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void hi() { String s12 = "hi ".concat(name); hello(s12); } public String hello(String s2) { return s2; } public String getToken() { return UUID.randomUUID() .toString() .replace("-", "") + name.hashCode(); } }
在class文件目录输入命令打印出字节码(-v是打印全面字节码信息,-p是涵盖所有成员):
javap -v -p ByteCodeT
字节码:
警告: 二进制文件ByteCodeT包含com.lims.pracpro.jdkprac.ByteCodeT Classfile /E:/Code/flickeringproject/pracpro/target/classes/com/lims/pracpro/jdkprac/ByteCodeT.class Last modified 2020-9-17; size 1319 bytes MD5 checksum 1c5e715a75b59bba2b0228e7757fa33d Compiled from "ByteCodeT.java" public class com.lims.pracpro.jdkprac.ByteCodeT minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #18.#40 // java/lang/Object."<init>":()V #2 = Fieldref #17.#41 // com/lims/pracpro/jdkprac/ByteCodeT.name:Ljava/lang/String; #3 = String #42 // hi #4 = Methodref #43.#44 // java/lang/String.concat:(Ljava/lang/String;)Ljava/lang/String; #5 = Methodref #17.#45 // com/lims/pracpro/jdkprac/ByteCodeT.hello:(Ljava/lang/String;)Ljava/lan g/String; #6 = Class #46 // java/lang/StringBuilder #7 = Methodref #6.#40 // java/lang/StringBuilder."<init>":()V #8 = Methodref #47.#48 // java/util/UUID.randomUUID:()Ljava/util/UUID; #9 = Methodref #47.#49 // java/util/UUID.toString:()Ljava/lang/String; #10 = String #50 // - #11 = String #51 // #12 = Methodref #43.#52 // java/lang/String.replace:(Ljava/lang/CharSequence;Ljava/lang/CharSeque nce;)Ljava/lang/String; #13 = Methodref #6.#53 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBu ilder; #14 = Methodref #43.#54 // java/lang/String.hashCode:()I #15 = Methodref #6.#55 // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; #16 = Methodref #6.#49 // java/lang/StringBuilder.toString:()Ljava/lang/String; #17 = Class #56 // com/lims/pracpro/jdkprac/ByteCodeT #18 = Class #57 // java/lang/Object #19 = Utf8 name #20 = Utf8 Ljava/lang/String; #21 = Utf8 <init> #22 = Utf8 ()V #23 = Utf8 Code #24 = Utf8 LineNumberTable #25 = Utf8 LocalVariableTable #26 = Utf8 this #27 = Utf8 Lcom/lims/pracpro/jdkprac/ByteCodeT; #28 = Utf8 getName #29 = Utf8 ()Ljava/lang/String; #30 = Utf8 setName #31 = Utf8 (Ljava/lang/String;)V #32 = Utf8 hi #33 = Utf8 s12 #34 = Utf8 hello #35 = Utf8 (Ljava/lang/String;)Ljava/lang/String; #36 = Utf8 s2 #37 = Utf8 getToken #38 = Utf8 SourceFile #39 = Utf8 ByteCodeT.java #40 = NameAndType #21:#22 // "<init>":()V #41 = NameAndType #19:#20 // name:Ljava/lang/String; #42 = Utf8 hi #43 = Class #58 // java/lang/String #44 = NameAndType #59:#35 // concat:(Ljava/lang/String;)Ljava/lang/String; #45 = NameAndType #34:#35 // hello:(Ljava/lang/String;)Ljava/lang/String; #46 = Utf8 java/lang/StringBuilder #47 = Class #60 // java/util/UUID #48 = NameAndType #61:#62 // randomUUID:()Ljava/util/UUID; #49 = NameAndType #63:#29 // toString:()Ljava/lang/String; #50 = Utf8 - #51 = Utf8 #52 = NameAndType #64:#65 // replace:(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/S tring; #53 = NameAndType #66:#67 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #54 = NameAndType #68:#69 // hashCode:()I #55 = NameAndType #66:#70 // append:(I)Ljava/lang/StringBuilder; #56 = Utf8 com/lims/pracpro/jdkprac/ByteCodeT #57 = Utf8 java/lang/Object #58 = Utf8 java/lang/String #59 = Utf8 concat #60 = Utf8 java/util/UUID #61 = Utf8 randomUUID #62 = Utf8 ()Ljava/util/UUID; #63 = Utf8 toString #64 = Utf8 replace #65 = Utf8 (Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String; #66 = Utf8 append #67 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #68 = Utf8 hashCode #69 = Utf8 ()I #70 = Utf8 (I)Ljava/lang/StringBuilder; { private java.lang.String name; descriptor: Ljava/lang/String; flags: ACC_PRIVATE public com.lims.pracpro.jdkprac.ByteCodeT(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 11: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/lims/pracpro/jdkprac/ByteCodeT; public java.lang.String getName(); descriptor: ()Ljava/lang/String; flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: getfield #2 // Field name:Ljava/lang/String; 4: areturn LineNumberTable: line 15: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/lims/pracpro/jdkprac/ByteCodeT; public void setName(java.lang.String); descriptor: (Ljava/lang/String;)V flags: ACC_PUBLIC Code: stack=2, locals=2, args_size=2 0: aload_0 1: aload_1 2: putfield #2 // Field name:Ljava/lang/String; 5: return LineNumberTable: line 19: 0 line 20: 5 LocalVariableTable: Start Length Slot Name Signature 0 6 0 this Lcom/lims/pracpro/jdkprac/ByteCodeT; 0 6 1 name Ljava/lang/String; public void hi(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=2, args_size=1 0: ldc #3 // String hi 2: aload_0 3: getfield #2 // Field name:Ljava/lang/String; 6: invokevirtual #4 // Method java/lang/String.concat:(Ljava/lang/String;)Ljava/lang/Stri ng; 9: astore_1 10: aload_0 11: aload_1 12: invokevirtual #5 // Method hello:(Ljava/lang/String;)Ljava/lang/String; 15: pop 16: return LineNumberTable: line 23: 0 line 24: 10 line 25: 16 LocalVariableTable: Start Length Slot Name Signature 0 17 0 this Lcom/lims/pracpro/jdkprac/ByteCodeT; 10 7 1 s12 Ljava/lang/String; public java.lang.String hello(java.lang.String); descriptor: (Ljava/lang/String;)Ljava/lang/String; flags: ACC_PUBLIC Code: stack=1, locals=2, args_size=2 0: aload_1 1: areturn LineNumberTable: line 28: 0 LocalVariableTable: Start Length Slot Name Signature 0 2 0 this Lcom/lims/pracpro/jdkprac/ByteCodeT; 0 2 1 s2 Ljava/lang/String; public java.lang.String getToken(); descriptor: ()Ljava/lang/String; flags: ACC_PUBLIC Code: stack=4, locals=1, args_size=1 0: new #6 // class java/lang/StringBuilder 3: dup 4: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V 7: invokestatic #8 // Method java/util/UUID.randomUUID:()Ljava/util/UUID; 10: invokevirtual #9 // Method java/util/UUID.toString:()Ljava/lang/String; 13: ldc #10 // String - 15: ldc #11 // String 17: invokevirtual #12 // Method java/lang/String.replace:(Ljava/lang/CharSequence;Ljava/lan g/CharSequence;)Ljava/lang/String; 20: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/la ng/StringBuilder; 23: aload_0 24: getfield #2 // Field name:Ljava/lang/String; 27: invokevirtual #14 // Method java/lang/String.hashCode:()I 30: invokevirtual #15 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 33: invokevirtual #16 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 36: areturn LineNumberTable: line 32: 0 line 33: 10 line 34: 17 line 35: 27 line 32: 36 LocalVariableTable: Start Length Slot Name Signature 0 37 0 this Lcom/lims/pracpro/jdkprac/ByteCodeT; } SourceFile: "ByteCodeT.java"