一、值传递和引用传递的区别
方法调用是编程语言中非常重要的一个特性,在方法调用时,通常需要传递一些参数来完成特定的功能。
Java语言提供了两种参数传递的方式:值传递和引用传递。
(1)值传递
在方法调用中,实参会把它的值传递给形参,形参只是用实参的值初始化一个临时的存储单元,因此形参与实参虽然有着相同的值,但是却有着不同的存储单元,因此对形参的改变不会影响实参的值。
(2)引用传递
在方法调用中,传递的是对象(对象地址),这时形参与实参的对象指向同一块存储单元,因此对形参的修改就会影响实参的值。
在Java语言中,8种基本数据类型在传递参数时都是按值传递,而包装类型在传递参数时是按引用传递的。
package com.haobi;
/*
* 值传递&引用传递
*/
public class PassParameter {
public static void testPassParamter(StringBuffer sb, int n) {
sb.append(" World");//引用
n = 8;//值
}
public static void main(String[] args) {
int i= 1;
StringBuffer s = new StringBuffer("Hello");
testPassParamter(s, i);
System.out.println(s);
System.out.println(i);
}
}
//程序输出结果如下:
Hello World
1
二、引用传递Demo及其内存分析
(1)示例一
package com.haobi;
public class Test1 {
public static void main(String[] args) {
String s = "Hello";
System.out.println(s);
tell(s);
System.out.println(s);
}
public static void tell(String str) {
str = "World";
}
}
//程序输出结果如下:
Hello
Hello
内存分析:
原因分析:String类型里的数据是不可更改的
(2)示例二
package com.haobi;
class Ref{
String temp = "Hello";
}
public class Test2 {
public static void main(String[] args) {
Ref r = new Ref();
r.temp = "World";
System.out.println(r.temp);
tell(r);
System.out.println(r.temp);
}
public static void tell(Ref ref) {
ref.temp = "World!!!";
}
}
//程序输出结果如下:
World
World!!!
内存分析:
三、基本数组和引用数组
在Java中,数组属于引用数据类型。
数组对象在堆中存储,数组变量属于引用类型,存储数组对象的地址信息,指向数组对象。
数组元素可以是任何类型,当然也包括引用类型。
(1)基本数组
int[] arr = new int[3];//①
arr[1] = 100;//②
内存分析:
(2)引用数组
引用类型数组的默认初始值都是null。
如果希望每一个元素都指向具体的对象,需要针对每一个数组元素进行“new”运算。
class Cell{
int row, col;
Cell(int row, int col){
this.row = row;
this.col = col;
}
}
...
Cell[] cells = new Cell[4];//①下附详细解释
cells[0] = new Cell(1, 2);//②
cells[1] = new Cell(3, 4);//③
内存分析:
注:上述程序中,new Cell[4]实际是分配了4个空间用于存放4个Cell类型的引用,并不是分配了4个Cell类型的对象。