Java内存分配为: 栈,堆,方法区,本地方法栈和寄存器
字节码文件加载时进入的内存方法区,方法运行区域为栈,变量也是存储在栈中,new出来的东西会在堆内存中开辟空间并产生地址。
public class ArrayDemo { public static void main(String[] args) { int a = 10; int[] arr = new int[]{11,22,33}; arr[0] = 44; arr[1] = 55; arr[2] = 66; System.out.println(arr[0]); System.out.println(arr[1]); System.out.println(arr[2]); } }
数组内存图,字节码文件将类加载时进入的内存是方法区,在方法区中再调用方法进入栈内存,变量在栈内存中存储,创建数组的话,他会现在栈中开辟内存区域,之后因为要new一个数组对象,因此要进入堆内存开辟空间这个时候再将要存的值存入数组中,然后再将这个空间的地址值传入到刚刚数组在栈内存开辟的空间内,这样一个数组的创建就创建好了。
方法的调用流程:方法没有被调用的时候,在方法区中的字节码文件中存放,方法被调用的时候,需要进入到栈内存中运行。
public class FucDemo { public static void main(){ study(); } private static void study() { eat(); System.out.println("学习"); sleep(); } private static void sleep() { System.out.println("睡觉"); } private static void eat() { System.out.println("吃饭"); } }
这个程序的方法流程:先将字节码 FucDemo.class字节码文件加载进方法区内,此时方法区内有 main study sleep eat, 程序开始运行,将main方法加载进栈内存,main会去调用study(),study方法去找eat()方法 ,eat方法执行后出栈,此时study()方法内再执行输出文字学习,再去调sleep()方法,此时study方法又需要暂停,sleep执行完输出睡觉之后出栈,此时study也调用完了,study也出栈,然后main方法也调用完毕,最后也出栈。
public class CanShuDemo { public static void main(String[] args) { int a = 10; change(a); System.out.println(a); } private static void change(int a) { System.out.println(a); a = 20; System.out.println(a); }
基本类型的参数传递:比如a变量 实际上他是复制了10的值传入change方法可以看成change(10),然后把10传递给change方法里面的形参变量a,改变a的值只是改变了change方法中形参的值而不是实参的值
引用类型的参数传递:传递地址值到形参
public class MethodDemo2 { public static void main(String[] args) { int[] arrs = {10,20,30}; change(arrs); System.out.println(arrs[1]); } private static void change(int[] arrs) { System.out.println("方法内部2:" + arrs[1]); //20 arrs[1] = 222; System.out.println("方法内部2: " + arrs[1]); //222 } }
change方法会通过你传递的地址值,通过你传递的地址值找到你堆内存中的数组,再将你数组中的值给修改。这也是跟基本数据类型值传递不同的地方。