java代码1:
package com.bytecode; public class Wizard { private int age; public Wizard() { this.age = 100; } }
javap -v Wizard.class 得到字节码:
Classfile /D:/Users/Administrator/workspace/TestJava/bin/com/bytecode/Wizard.class Last modified 2018-3-14; size 311 bytes MD5 checksum 301ffac27f2fa331e20b98a912914551 Compiled from "Wizard.java" public class com.bytecode.Wizard SourceFile: "Wizard.java" minor version: 0 major version: 51 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Class #2 // com/bytecode/Wizard #2 = Utf8 com/bytecode/Wizard #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Utf8 age #6 = Utf8 I #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Methodref #3.#11 // java/lang/Object."<init>":()V #11 = NameAndType #7:#8 // "<init>":()V #12 = Fieldref #1.#13 // com/bytecode/Wizard.age:I #13 = NameAndType #5:#6 // age:I #14 = Utf8 LineNumberTable #15 = Utf8 LocalVariableTable #16 = Utf8 this #17 = Utf8 Lcom/bytecode/Wizard; #18 = Utf8 SourceFile #19 = Utf8 Wizard.java { public com.bytecode.Wizard(); flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: invokespecial #10 // Method java/lang/Object."<init>":()V 4: aload_0 5: bipush 100 7: putfield #12 // Field age:I 10: return LineNumberTable: line 6: 0 line 7: 4 line 8: 10 LocalVariableTable: Start Length Slot Name Signature 0 11 0 this Lcom/bytecode/Wizard; }
在构造函数Wizard()中,局部变量表0处是this引用。
指令 | 描述 | 操作数栈 |
aload_0 | this引用入操作数栈 | this |
invokespecial #10 | 调用Object类的<init>方法,消耗栈中的this引用 | |
aload_0 | this引用再次推入操作数栈 | this |
bipush 100 | 把整数100推入操作数栈 | this, 100 |
putfield #12 | 调用this -> Wizard.age = 100,消耗栈中的this和100 |
java代码2:
public class Wizard { private int age; private void grow() { this.age += 1; } }
javap -v -p Wizard.class 得到字节码:
Classfile /D:/Users/Administrator/workspace/TestJava/bin/com/bytecode/Wizard.class Last modified 2018-3-15; size 375 bytes MD5 checksum 1910939ad3f794132f14da4c1c417e96 Compiled from "Wizard.java" public class com.bytecode.Wizard SourceFile: "Wizard.java" minor version: 0 major version: 51 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Class #2 // com/bytecode/Wizard #2 = Utf8 com/bytecode/Wizard #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Utf8 age #6 = Utf8 I #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Methodref #3.#11 // java/lang/Object."<init>":()V #11 = NameAndType #7:#8 // "<init>":()V #12 = Utf8 LineNumberTable #13 = Utf8 LocalVariableTable #14 = Utf8 this #15 = Utf8 Lcom/bytecode/Wizard; #16 = Utf8 grow #17 = Fieldref #1.#18 // com/bytecode/Wizard.age:I #18 = NameAndType #5:#6 // age:I #19 = Utf8 SourceFile #20 = Utf8 Wizard.java { private int age; flags: ACC_PRIVATE public com.bytecode.Wizard(); flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #10 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 3: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/bytecode/Wizard; private void grow(); flags: ACC_PRIVATE Code: stack=3, locals=1, args_size=1 0: aload_0 1: dup 2: getfield #17 // Field age:I 5: iconst_1 6: iadd 7: putfield #17 // Field age:I 10: return LineNumberTable: line 7: 0 line 8: 10 LocalVariableTable: Start Length Slot Name Signature 0 11 0 this Lcom/bytecode/Wizard; }
关注grow方法:
指令 | 描述 | 操作数栈 |
aload_0 | this入栈 | this |
dup | 栈顶的this复制一份,再入栈 | this, this |
getfield #17 | this出栈,this.age入栈 | this, this.age |
iconst_1 | 常数1入栈 | this, this.age, 1 |
iadd | 栈顶的2个值相加 | this, (this.age + 1) |
putfield #17 | 给成员赋值,消耗两个栈元素 |