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”变量就无所谓了