public class Test{ public static void main(String[] arg){ Person aaaaaaaaaaaaa = new Person(); change(aaaaaaaaaaaaa); } public static void change(Person p) { p.name = "mao"; } } public class Person{ String name; }
对上面Test编译产生如下java指令
Classfile /F:/Test.class Last modified 2017-5-26; size 419 bytes MD5 checksum b3b57626cd3396f8e3ce811d3b6a54ee Compiled from "Test.java" public class Test minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #8.#19 // java/lang/Object."<init>":()V #2 = Class #20 // Person #3 = Methodref #2.#19 // Person."<init>":()V #4 = Methodref #7.#21 // Test.change:(LPerson;)V #5 = String #22 // mao #6 = Fieldref #2.#23 // Person.name:Ljava/lang/String; #7 = Class #24 // Test #8 = Class #25 // java/lang/Object #9 = Utf8 <init> #10 = Utf8 ()V #11 = Utf8 Code #12 = Utf8 LineNumberTable #13 = Utf8 main #14 = Utf8 ([Ljava/lang/String;)V #15 = Utf8 change #16 = Utf8 (LPerson;)V #17 = Utf8 SourceFile #18 = Utf8 Test.java #19 = NameAndType #9:#10 // "<init>":()V #20 = Utf8 Person #21 = NameAndType #15:#16 // change:(LPerson;)V #22 = Utf8 mao #23 = NameAndType #26:#27 // name:Ljava/lang/String; #24 = Utf8 Test #25 = Utf8 java/lang/Object #26 = Utf8 name #27 = Utf8 Ljava/lang/String; { public Test(); 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 1: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=1 0: new #2 // class Person 3: dup 4: invokespecial #3 // Method Person."<init>":()V 7: astore_1 8: aload_1 9: invokestatic #4 // Method change:(LPerson;)V 12: return LineNumberTable: line 3: 0 line 4: 8 line 5: 12 public static void change(Person); descriptor: (LPerson;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: ldc #5 // String mao 3: putfield #6 // Field Person.name:Ljava/lang/St ring; 6: return LineNumberTable: line 9: 0 line 10: 6 }
第一:我们看不到任何的“aaaaaaaaa”变量名的影子,因为这个变量其实就是一个内存地址,变量名是为了程序员好操作这块地址,而任何对这个地址存储数据的操作编译器都能找到对应地址。
第二:astore_1表示将栈顶引用型数值存入第二个本地变量,aload_1意思是将第二个引用类型本地变量推送至栈顶,也就是把存在第二个本地变量中的指向堆中新建Person对象的地址放到栈顶,change方法第一个指令就是aload_0(将第一个引用类型变量置于栈顶),所以change方法中的p.name="mao"就是修改堆中的新建person对象,main方法中的变量“aaaaaaaaa”指向同一个对象就受影响
但是如果change方法内是p = new Person()那就是方法的第一个引用类型变量指向另一个person对象,main中的“aaaaaaaa”变量就无所谓了