Java 方法中参数的传递方式

时间:2022-02-08 21:29:54

在《Java核心技术 卷一 基础知识》第4.5节中专门讲解了方法参数,里面有一句话:Java程序设计语言总是采用按值调用。整个一节都是围绕着一句话来进行讲解,内容比较抽象,后来在*上面看到了相关内容的精彩讨论(Is Java “pass-by-reference” or “pass-by-value”?),在此做近一步整理。

首先先明确几个术语,基本数据类型引用类型(对象引用)是方法中参数的两种类型,按值调用按引用调用是方法中参数的两种传递方式。注意这里的几个术语是一般程序设计语言中的术语,并非特指Java。

毋庸置疑的是,在Java中,方法的参数类型有基本数据类型和对象引用。例如,foo(int a)的参数类型是基本数据类型,foo(String a)的参数类型是引用类型。下面分别对这两类情况进行说明。

1. 基本数据类型作参数

针对于参数类型是基本数据类型的情况,代码如下:

public class Test {

public static void tripleValue(double x){
  x
= 3*x;
  System.out.println(
"在方法tripleValue() 内部, x = " + x);//x=6.0
}

public static void main(String[] args){
  
double a = 2;
  System.out.println(
"调用方法 tripleValue() 之前, a = " + a);// a = 2.0
  tripleValue(a);
  System.out.println(
"调用方法 tripleValue() 之后, a = " + a);// a = 2.0
}
}

输出

调用方法 tripleValue() 之前, a = 2.0
在方法tripleValue() 内部, x
= 6.0
调用方法 tripleValue() 之后, a
= 2.0

上面这个比较简单,输出结果在预料之中,借用这个简单的例子,通过绘制图形的方式,来表示Java虚拟机是样分配内存的。

首先 double a = 2; 声明类一个基本数据类型a并为它赋予了初值2, Java虚拟机在栈顶分配了一块8字节的内存存储数值2.0。

 Java 方法中参数的传递方式

前面声明的double类型的变量a属于基本数据类型,tripleValue方法以按值调用的方式调用a,此时传入tripleValue方法中的是a的一个拷贝。

Java 方法中参数的传递方式

当tripleValue方法内部执行 x = 3*x; 语句时实际上仅仅对a的拷贝进行了乘3操作,而a本身的值没有发生改变。

Java 方法中参数的传递方式

2. 对象引用作参数

先亮代码:

public class HelloWorld
{
public static void reName(String name){
name
+= "re";
}

public static void main(String[] args){
String oldName
= "Bob";
System.out.println(oldName);
reName(oldName);
System.out.println(oldName);

}
}

输出:

Bob
Bob

 与基础数据类型double不同,String属于引用类型,即变量存的是对象的地址。同样,上面代码main方法中声明oldName之后,Java虚拟机内存分配的情况可用下图表示。

Java 方法中参数的传递方式

方法reName调用oldName时,我们先不管它是按照什么方式调用,先看reName方法质执行的过程。当reName方法内部执行语句 name += "re"; 时,JVM将创建一个新的String对象"reBob",即相当于执行了语句name = new String("reName"), name指向"reName"。

此时,若reName是按引用调用"Bod"对象的引用oldName, 则oldName和name都将指向新的对象"reBod";若reName按值调用"Bod"对象的引用oldName, 则name和oldName将指向不同的对象。从执行结果中我们可以看到,执行reName之后再打印oldName,结果仍然是"Bob",这表明oldName指向的对象仍然为"Bob"。

故在Java中,对象引用作参数时,方法按值调用实参,即方法得到的是对象引用的一个拷贝。

Java 方法中参数的传递方式

所以说:“Java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,特别是方法不能修改传递给它的任何参数变量的内容”。

 

 

 

 

 

 

 

 

调用方法 tripleValue(double x) 时,