java方法体的变量内存分配

来源:互联网 发布:淘宝网上衣 编辑:程序博客网 时间:2024/06/06 20:51

java方法体的变量作为返回值的原理

       在读《代码大全》时看到,c语言在方法中不要返回指向局部变量的指针,想到了java中是可以返回任意类型,没有限制,这是怎么实现的。经过深入了解,c语言是可以返回局部变量指针,但是这个指针地址必须不是指向栈内存。java为什么可以返回任意类型,因为java控制了引用类型不允许在栈内存中创建,java在栈的内存分配上设定了栈只存放基本类型的变量数据和引用类型的引用。

1.java方法的返回类型

1.void  无返回值;
2.基本类型  byte、short、int、long、float、double、boolean、char;
3.引用类型  String、Enum、类等;
由于void没有返回值,不需要考虑,需要讨论的是返回值是基本类型和引用类型的实现原理。

2.java运行时的数据存储

1.寄存器(register)  存取速度最快,编译器根据需求进行分配,我们在程序中无法控制;
2.栈(stack)  存取速度比较快,存放基本类型的变量数据和引用类型的引用;(注意引用类型本身不存放在栈中)
3.堆(heap) 存取速度较慢,运行时动态分配内存,存放对象实例,New的对象实例、数组等;
4.静态存储(static storage)  存储static关键字修饰的数据;
5.常量池(Constant Pool Table)  存放各种字面量和符号引用;
方法返回值的的数据存储基本使用基本类型-栈(stack)和引用类型-堆(heap)

3.java方法返回值的原理


public  int isNotEmpty(String s){    if(null!=s && s.length()>0)        return 1;    return 0;}

       返回类型当时值类型,假如需要执行这个方法时,JVM线程的栈中会创建一个栈帧,把这个方法的局部变量表、操作数栈、动态链接、方法出口等信息存储到栈帧中,isNotEmpty方法的执行就是栈帧在虚拟机栈中从入栈到出栈的过程,方法执行完毕后,释放掉栈帧占用的内存,返回值消失。

public static void main(String[] args){int a=isNotEmpty(null);}
       现在调用isNotEmpty方法并把返回值赋值给一个整形变量,这时在执行到方法的出口时,方法会把返回的值复制一份,put到main函数的栈中,isNotEmpty方法执行完毕后,释放掉栈帧占用的内存,然后进行赋值运算。
public static void main(String[] args){int arr[]=getArray();}public int[] getArray(){        int a[]=new int[]{1,2};        return a;}


       如果这时返回类型是引用类型,是怎么实现的,int a[]在getArray方法执行时,在堆中申请内存空间存储数据,然后数组a指向该内存地址,在getArray方法的栈帧中存放的是数组a地址,这时这个地址相当于值类型了,在getArray方法执行到方法的出口时,把地址的值复制一份,put到main函数的栈中,方法执行完毕后,释放掉栈帧占用的内存,这时数组a消失,但是数组a在堆中申请的空间并没有被GC回收,执行赋值操作后,数组arr的地址就指向了数组a申请的空间。这就实现了返回引用类型

0 0
原创粉丝点击