【static】---- 关键字在内存--图解

来源:互联网 发布:welsh算法 编辑:程序博客网 时间:2024/05/16 23:54

Static 关键字在内存中的图解:

源码:

//写一个人类class Person{      private String name;      private int age;      static String country="CN";      public Person(String name,int age)      {           this.name=name;           this.age=age;      }           public void show()      {           System.out.println(Person.country+":"+this.name+":"+this.age);      }           public static void method()      {           System.out.println(Person.country);      }} public class Static_Demo2{      public static void main(String[]args)      {           Person.method();                     Person p=new Person("java",32);           p.show();      }}


内存分析:

1.在内存中划分区域,栈的区域,堆的区域,方法区的区域。(如图1)


2.方法都是存在方法区中的。当StaticDemo2被执行的时候,加载类,StaticDemo2类已经进内存了。

3.先在内存中划分了一片空间,这个类叫做StaticDemo2(如图2)。


这个类里有一个成员方法,StaticDemo2(){}方法加载进来,是这个类中的默认构造函数(如图3)。


4.接着加载静态方法main,是在静态方法区里的,静态区专门存储静态的数据,StaticDemo2类里的静态方法main就是存储在这块静态区里(如图4)。


5.静态区里的方法和非静态区里的方法都是共享的。非静态区里的成员都有一个this,因为非静态区的内容只能被对象调用;而到了静态区里它们都是所属于类名,只能被类名调用。

6.这个时候主函数main进栈(如图5)。


Main方法进栈以后开始运行里面的内容(如图6)。


7.接着运行第一句Person.method();这个是这个类才加载,这个它就开始找classpath路径下有没有Person.class文件,如果没有设置classpath,它就默认在当前路径下找。找到以后就把Person.class文件加载进内存,一加载就在方法区中分配空间了。Person类进内存了,紧接着person的构造函数(Person(Stringname,int age){this.name=name;this.age=age;})加载进来,voidshow(){sop();}也加载进来(如图8),


在静态方法区中static void method(){}也加载进来,staticString country也加载进来了(如图9)。


8.加载完了之后,这个时候,执行第一句:Person.method();是用类名调用,用类名调用只能找静态区。在静态区找,在Person这个所属类的静态区中 ,有静态方法method(),这个时候method方法开始进栈。开始执行method方法,如果有变量开辟栈空间,没有变量直接执行。接着执行语句System.out.println(Person.country);在静态方法区里找Person类里的变量country。执行完之后弹栈(如图10)。


9.接着执行第二句:Person p=new Person(“java”,  20);,这个时候在主函数里多了一个p(如图12),


接着执行右边new person(“java”,20);,new一个person在堆里开辟一块空间(如图13)。


Person对像里有变量name,age,,由于newperson(“java”,20)是调用了person类里的构造方法,所以此时构造函数进栈(如图14)。


进栈以后,person构造函数先有一个this,这this的值是堆里对象的地址0x0056,接着将两个参数“java”,“20”分别赋给person构造函数的局部变量name,age(如图15),

接着执行方法区里的Person构造函数(如图16),


this.name=name;,将局部变量name的值“java”赋给了this所指向的对象的name。this同理。


10.构造函数person()初始化完了之后,它弹栈了,弹完栈了,右边初始化完毕,这个时候将右边的地址值赋给左边的变量p,变量p指向了对象(如图18)。


11.执行第三句:p.show();,方法区里的show()进栈,show进栈,它是非静态的,有所属this,this有p的地址值(如图19)。


接着执行输出语句System.out.println(Person.country+name+age),,执行person.country,在静态区里调用country,打印出country的值。Name,通过this.name在对象里调用,age,通过this.age在对象里调用。输出完以后show就弹栈了。最后的最后,主函数也弹栈了。所有程序结束(如图20)。





0 0