方法的参数传递机制

最近看到一道题目,尝试分析一下

public class TestBuMa {
    public static void main(String[] args){
        int i=1;
        String str="Hi";
        Integer num=2;
        int[] arr={1,2,3,4};
        MyData myData=new MyData();

        change(i,str,num,arr,myData);
        System.out.println("i="+i);
        System.out.println("str="+str);
        System.out.println("num="+num);
        System.out.println("arr="+ Arrays.toString(arr));
        System.out.println("myData.a="+myData.a);
    }
    public static  void  change(int j,String s,Integer n,int[] arr,MyData myData){
        j+=1;
        s+=",张三";
        n+=1;
        arr[0]+=1;
        myData.a+=1;
    }
}
class MyData{
    int a =10; 
}

jvm内存区域

image

根据java虚拟机内存区域,可以将上面数据类型存储区域进行划分

Java Heap 是 Java 虚拟机所管理的内存中最大的一块,它是所有线程共享的一块内存区域。几乎所有的对象实例,成员变量和数组都在这类分配内存。Java Heap 是垃圾收集器管理的主要区域,因此很多时候也被称为“GC堆”。根据 Java 虚拟机规范的规定,Java 堆可以处在物理上不连续的内存空间中,只要逻辑上是连续的即可。如果在堆中没有内存可分配时,并且堆也无法扩展时,将会抛出 OutOfMemoryError 异常。

方法区也是各个线程共享的内存区域,它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区域又被称为“永久代”。

栈,方法里的局部变量存在栈中,栈中有一个局部变量表用来存放方法参数和方法内部的局部变量,其存放的数据类型是编译器可知的基本数据类型,对象引用。局部变量表所属要的内存在编译阶段就会分配完成。

下面用图示展示main方法里的局部变量在jvm内存中的位置

image

image

虚拟机栈描述的是 Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧,栈它是用于支持续虚拟机进行方法调用和方法执行的数据结构。

执行change方法之后再看各变量的值。

 

image

执行完change之后当前私有区域的栈内存就会被回收因此最后执行结果是

1,Hi,2,[2,2,3,4],11

形参是基本数据类型则传递数据值

形参是引用数据类型传递的是地址值(注:String常量,包装类的对象不可变性)

原文地址:https://www.cnblogs.com/gyjx2016/p/12582477.html