Java中值传递及内存分配的理解
2014-04-11 14:54
204 查看
要理解Java中的值传递,首先得牢记一句话:
Java参数,不管是原始类型还是引用类型,传递的都是副本。
也有说法说是值传递,但我觉得用“副本”比较好理解吧。
在这里又涉及到Java程序运行中的内存分配问题,先这么简单地理解吧:
Java中把内存分为栈内存和堆内存。函数中的基本类型变量、对象的引用变量(注意:对象的引用本身就是一个变量)存放在栈内存中,而具体的对象所占用的内存则被分配到堆内存中。
举个例子:
当程序在函数中创建一个A类型对象a(执行语句A a=new A();)时,内存分配如下图(图画的丑,意思到了就行,请忍住吐槽= =):
其中a、s分别为A、String类型的引用变量。
清楚了这点之后,来看一小段代码:
int:1 String:a0
int:0 String:modifyString
int:0 String:a2
首先分析一下执行到22行时的内存分配情况:
接下来,在执行到
modifyInt(a0,1);
语句时,会在栈内存创建一个a0的副本(暂且称之为a),a也指向a0所指向的在堆内存中对象。当执行到modifyInt方法体内的
a.i=i;
语句时,因为a与a0所指向的堆内存一样,所以a.i等同于a0.i.此时修改就起作用了。
同理,modifyString(a1,"modifyString");也是一样。
继续往下走,在执行到
modifyReference(a2);时,创建了一个a2的副本(a),当执行到方法体内的
a=new A(3,"modifyReference");时,实际上时让a2的副本a指向了一块新的堆内存,而对a2毫无影响,a2所指向的堆内存也不会发生改变。
所以,当程序执行到26行时,内存情况如下:
这仅仅是本人对Java值传递的一些浅显认识和理解,若有误,欢迎大家指正!
Java参数,不管是原始类型还是引用类型,传递的都是副本。
也有说法说是值传递,但我觉得用“副本”比较好理解吧。
在这里又涉及到Java程序运行中的内存分配问题,先这么简单地理解吧:
Java中把内存分为栈内存和堆内存。函数中的基本类型变量、对象的引用变量(注意:对象的引用本身就是一个变量)存放在栈内存中,而具体的对象所占用的内存则被分配到堆内存中。
举个例子:
class A{ int a=0; String s="str"; }
当程序在函数中创建一个A类型对象a(执行语句A a=new A();)时,内存分配如下图(图画的丑,意思到了就行,请忍住吐槽= =):
其中a、s分别为A、String类型的引用变量。
清楚了这点之后,来看一小段代码:
package com.passing; public class Test { //修改A类型对象a中的int static void modifyInt(A a, int i) { a.i = i; } //修改A类型对象a中的String static void modifyString(A a, String s) { a.s = s; } //修改a的引用 static void modifyReference(A a) { a = new A(3, "modifyReference"); } public static void main(String[] args) { A a0 = new A(0, "a0"); A a1 = new A(0, "a1"); A a2 = new A(0, "a2"); modifyInt(a0, 1); modifyString(a1, "modifyString"); modifyReference(a2); a0.print(); a1.print(); a2.print(); } } class A { int i; String s; public A(int i, String s) { this.i = i; this.s = s; } public void print() { System.out.println("int:" + i + " String:" + s); } }输出:
int:1 String:a0
int:0 String:modifyString
int:0 String:a2
首先分析一下执行到22行时的内存分配情况:
接下来,在执行到
modifyInt(a0,1);
语句时,会在栈内存创建一个a0的副本(暂且称之为a),a也指向a0所指向的在堆内存中对象。当执行到modifyInt方法体内的
a.i=i;
语句时,因为a与a0所指向的堆内存一样,所以a.i等同于a0.i.此时修改就起作用了。
同理,modifyString(a1,"modifyString");也是一样。
继续往下走,在执行到
modifyReference(a2);时,创建了一个a2的副本(a),当执行到方法体内的
a=new A(3,"modifyReference");时,实际上时让a2的副本a指向了一块新的堆内存,而对a2毫无影响,a2所指向的堆内存也不会发生改变。
所以,当程序执行到26行时,内存情况如下:
这仅仅是本人对Java值传递的一些浅显认识和理解,若有误,欢迎大家指正!
相关文章推荐
- 通过函数分配内存,理解实参,形参之间的传递.
- 关于static静态变量的理解以及C中的内存区的分配
- 深入理解JVM:垃圾收集器与内存分配策略
- 深入理解JVM:垃圾收集器与内存分配策略
- 【深入理解JAVA虚拟机】之垃圾收集器与内存分配策略
- Java内存区域划分、内存分配原理(深入理解JVM一)
- 上午所学(jvm内存分配和shell排序算法的深入理解)
- 深入理解 JVM 系列:内存分配与回收策略
- Jvm(31),理解升级----通过JVM内存模型深入理解值传递和引用传递两种方式
- 深入理解Java 虚拟机读书笔记--第三章 垃圾收集器与内存分配策略
- .NET的堆和栈02,值类型和引用类型参数传递以及内存分配
- 【Java面试整理之JVM】深入理解JVM结构、类加载机制、垃圾回收GC原理、JVM内存分配策略、JVM内存泄露和溢出
- Java 基础【04】数组内存分配 引用传递 值传递
- 深入理解函数中分配内存的问题
- C语言缓冲区&内存分配的理解
- 深入理解java虚拟机----->垃圾收集器与内存分配策略(上)
- 子函数中为调用者分配内存的一些理解
- 理解内存分配
- 垃圾收集器与内存分配策略 (深入理解JVM二)
- c 函数传递参数 & 结构体内存分配