为了方便理解,暂时把元空间依旧当作方法区
程序刚开始执行,main先进栈,然后执行main方法中第一行代码,Student.teacherName = "阿玮老师"; 这行代码中去调用了Student类的静态变量teacherName并赋值为阿玮老师,此时就用到了Student这个类,所以在内存中就会把Student类的字节码文件加载到方法区,并在内存当中创建了一个单独存放静态变量的空间,我们可以把这个空间叫做静态区,在JDK8以前,它是在方法区里面的,但是到了JDK8以后,就把它挪到了堆内存中,在静态区里面就存着这个类所有的静态变量, 在这里需要注意,现在内存当中是没有对象的,因为代码还没有执行到new关键字,只有new关键字执行了,在内存中才有对象,可以发现静态是优先于对象的,静态变量是随着类的加载而加载的,优先于对象出现的,在以后我们还会用static修饰其它的内容,其它的内容也会去遵守这个规则,只要是用静态static修饰的,都是随着类的加载而加载,加载的时候是优先于对象出现在内存里面的接着执行main方法中的第二行代码,Student s1 = new Student();等号的左边相当于定义了一个变量s1,等号的右边有new关键字了,所以就在堆中开辟了一个空间,这个空间就是我们平时所说的对象,在这个空间里存放的是所有的非静态的成员变量,并将此空间的地址值赋值给s1,如果我想通过s1去访问静态变量,那么此时就会到静态区里去找对应的静态变量接着执行main方法中的第三行代码,s1.name = "张三";这里的s1记录的是地址值,所以这行代码是把张三赋值给对应空间的name,同理第三行代码,s1.name = 23;也相同接着执行main方法中的第四行代码,s1.show();用s1去调用show方法,这是show方法就会被加载进栈,因为此时show方法的调用者是s1,那么就会通过s1去找对应空间的name,age和静态区里面的teachName,show方法执行完毕后就会出栈接着执行main方法中的第五行代码,Student s2 = new Student();这行代码就是创建了第二个对象s2,与对象s1同理
接着执行main方法中的第六行代码,s2.show();通过s2在去调用show方法,此时show方法就会加载进栈,与s1.show();同理
通过上述图解我们可以发现:
1,静态区里面的这些变量是对象共享的,在内存当中只有一个
2,非静态的是每一个对象独有的,每一个对象里面都是单独存放的