java 方法参数-值调用,引用调用问题

(博客内容来自于core java卷一)

1. xx调用:程序设计语言中方法参数的传递方式:

引用调用(call by reference):表示方法接收的是调用者提供的变量地址。

值调用(call by value):表示方法接收的是调用者提供的值。

命名调用(call by name):已经成为历史。

2. Java使用值调用,而且只有值调用。也就是说方法得到的是参数值的一个拷贝,并不是参数值本身,所以,方法不能修改传递给它的的任何参数变量本身。

看下面代码:

public class test {

public static void main(String[] args) {

int percent = 10;

tripleValue(percent);

System.out.println(percent);

}

public static void tripleValue(int x){

x = x * 3;

}

}

输出:10

可以看到,无论怎样调用这个方法,执行之后,persent的值还是10。具体执行过程:

① x被初始化为persent的一个拷贝(也就是10)。这时x是x,persent是persent,只不过值相同。

② x被乘以3后等于30。但是persent仍然是10。

③ 这个方法结束后,参数变量x不再使用。

3. 然而,方法参数共有两种类型:基本数据类型(数字,布尔值);对象引用。

一个方法不可能修改一个基本数据类型的参数。而对象引用作为参数就不同了。这时,方法得到一个对象引用的拷贝。对象引用和其拷贝,同时引用着一个对象。

看下面代码:

public class test {

public static void main(String[] args) {

Circle c = new Circle();

c.r = 1;

bigger(c);

System.out.println(c.r);

}

public static void bigger(Circle c2){

C2.r = c2.r+3;

}

}

class Circle{

int r;

}

输出:4

具体执行过程:

① c2被初始化为c值的拷贝,这个值是一个对象的引用。

② bigger方法应用于这个对象引用。所以,c2和c同时引用的那个Circle对象的r值就增加了3。

③ 方法结束后,参数变量c2不再使用。c继续引用这个r值已经增加了3的Circle对象。

4.很多程序设计语言(特别是c++和Pascal)提供了两种参数传递的方式:值调用和引用调用。有些程序员认为java程序设计语言对对象采用的是引用调用,实际上这种理解是不对的。由于这种误解具有一定的普遍性,所以下面给出一个反例,来详细阐述一下这个问题。

首先编写一个交换两个圆对象的方法:

public static void swap(Circle x,Circle y){

Circle temp = x;

x = y;

y = temp;

}

如果java程序设计语言对对象采用的是引用调用的话,这个方法应该能够实现交换数据的效果:

Circle a = new Circle(1);

Circle b = new Circle(2);

swap(a,b);

System.out.println(a.r);

System.out.println(b.r);

输出:

1

2

但是,方法并没有改变存储在变量a和b中的对象引用。Swap方法的参数x和y被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝,a和b中的对象引用并没有变化。最终,白费力气,在方法结束时参数变量x和y被丢弃了。这个过程说明:java对对象采用的不是引用调用,而是值传递。

5.总结:

(1)一个方法不能修改一个基本数据类型的参数(即数值型和布尔类型值)。

(2)一个方法可以通过对象参数对其引用的对象状态进行操控。

(3)一个方法不能让对象参数引用一个新的对象。

注意:c++有值调用和引用调用。引用参数标有&符号。例如,可以轻松低实现void swap(Circle& a,Circle& b)方法,实现修改它们的引用参数的目的。

上一篇:HDU4901 The Romantic Hero 计数DP


下一篇:c/c++ 大于等于 大于 时间效率比较