您的位置:首页 > 编程语言 > Java开发

Java中值传递及内存分配的理解

2014-04-11 14:54 204 查看
要理解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值传递的一些浅显认识和理解,若有误,欢迎大家指正!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息