java类实例化时内存中发生的变化(图解)
一.成员变量和局部变量调用的区分
首先我们根据下面一段代码来区分成员变量和局部变量的调用。
package example02;
public class Student {
String name ;//定义成员变量
int age ; //定义成员变量
void Speak() {
System.out.println("学生的姓名是:"+name);
System.out.println("学生的年龄是:"+age);
System.out.println("############");
}
public static void main(String[] args) {
Student stu = new Student() ; //实例化对象stu
stu.name = "张三" ; //赋值
stu.age = 18; //赋值
stu.stuid = "1008611" ; //赋值
stu.Speak(); //调用方法speak
}
}
【成员变量】:在类中直接定义的变量
例如以上程序,在类Student.class中定义了成员变量 String name , int age, String stuid ,和一个成员方法 void Speak() 。通过实例化stu给成员变量赋值并调用成员函数。
package example02;
public class Student {
public static void main(String[] args) {
String name = "李四"; //局部变量
int age = 20; //局部变量
String stuid = "1001011" ; //局部变量
System.out.println("学生的姓名是:"+name);
System.out.println("学生的年龄是:"+age);
}
}
【局部变量】:在方法体内定义的变量
例如以上程序,在类main函数方法体中定义了局部变量 String name , int age。在方法体内可以直接打印输出。
二. 类实例化时内存中发生的变化
1.首先我们对下面一段代码进行代码分析
package example02;
public class Student {
String name ;//定义成员变量
int age ; //定义成员变量
String stuid ; //定义成员变量
void Speak() {
System.out.println("学生的姓名是:"+name);
System.out.println("学生的年龄是:"+age);
System.out.println("学生的学号是:"+stuid);
System.out.println("############");
}
public static void main(String[] args) {
Student stu = new Student() ; //实例化对象stu
stu.name = "张三" ; //赋值
stu.age = 18; //赋值
stu.stuid = "1008611" ; //赋值
stu.Speak(); //调用方法speak
}
}
【代码解析】
这段代码首先定义了三个成员变量 String name , int age, String stuid ,并且三个成员变量都没有赋初始值。紧接着定义了一个成员方法 void Speak() ,这个方法用来打印输出学生的姓名,学生的年龄和学生的学号。
在main() 函数里面我们又定义了三个相同变量String name , int age, String stuid ,但是这三个变量是局部变量。
在main() 函数里面机器石实例化对象stu , 内存中在堆区内会给实例化对象stu 分配一片地址,紧接着我们对实例化对象stu进行了赋值。stu调用成员方法 void Speak() 。mian()函数打印输入学生的姓名,学生的年龄和学生的学号。系统执行完毕。
2.图解法展示内存中的变化
我们知道,java中在类的实例化过程中,内存中会使用这三个区域,栈区,堆区和方法区。
在程序执行的过程中,首先,类中的成员变量和方法体进入到方法区。
然后main()函数方法体进入栈区,这一过程叫做进栈(压栈)定义了一个用于指向Student类的实例
在堆区内创建一个实例 Student stu = new Student()的实例。然后将成员变量和成员方法放在new实例中。将成员变量放在new实例中的过程中是取成员方法的地址值。
接下来, stu.name = “张三” ; stu.age = 18; stu.stuid = “1008611” ; 先在栈区找到stu,然后根据地址值找到new Studnet() 进行赋值操作。
然后调用方法体void speak(),在调用方法体的过程中,先在栈区找到stu,后根据地址值找到new Studnet() 进行方法体调用。
在方法体void speak()被调用完成后,就会立刻马上从栈内弹出(出站)
最后,在main()函数完成后,main()函数也会出栈
以上便是完整的java类实例化时内存中发生的变化。