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

Java中参数传递类型只有值传递

2014-03-01 11:02 316 查看
Java核心技术卷I里有一个结论我觉得挺有意思的:java中没有引用传递,只有值传递

首先看定义:

值传递,是指方法接收的是调用者提供的值

引用传递,是指方法接收的是调用者提供的变量地址

以前学习C++时把参数传递分为值传递和引用传递,国内的不少java教材愿意把对象的传递理解是引用传递,为什么它们会这么说呢?可以看下面一个例子:
import java.util.Calendar;  
public class ChangeValue {  
    public static void main(String[] args) {  
        Calendar oc = Calendar.getInstance();  
        System.out.println("origin:"+oc.getTime());  
        changeDate(oc);  
        System.out.println("after:"+oc.getTime());        
    }  
      
    static void changeDate(Calendar pd){  
        pd.set(1970, 1, 1);  
    }  
}


某时刻程序输出:
origin:Thu Jan 05 21:15:59 CST 2012 
after:Sun Feb 01 21:15:59 CST 1970


oc对象的值改变了,很多人就认为java对象传递实际上是引用传递。

过程应该是这样的:

运行changeDate这个函数时,方法得到的是对象引用的拷贝,oc和pd同时引用同一个对象,所以函数运行结束后,pd已经消失了,但是对引用对象的更改却也影响了oc所引用的同一对象,结合对之前的定义理解,这应该是值传递的过程(传递的是对象引用的拷贝)。

-----------------------------------------------------------------------------------------------

此段代码是自己补充;

public class Test4 { 
    public static void main(String[] args) {
        String s = "abc";
        Person person = new Person("ljs",23);
         
        System.out.println(s);//abc
        System.out.println(person.getAge()+":"+person.getName());//23:ljs
         
        changeInteger(s,person);
         
        System.out.println(s);//abc
        System.out.println(person.getAge()+":"+person.getName());//100:change
    }
    public static void changeInteger(final String str,Person p){
        str.replace('a', 'x');
        p.setAge(100);
        p.setName("change");
    }
}


现在我们看看这段代码和上面代码做个比较,Person对象改变了,Sting也是对象,却没有改变属性,这是为什么?

我们先看看代码运行过程: 方法得到的是对象引用的拷贝,s和str同时引用同一个对象,

但是,这个对象有点特别,它是String

而String最大的特点 : 就是一旦被初始化就不会改变(final常量的特性)【String对象放在常量池中 】

-------------------------------------------------------------------------------------------------

以下附上另一个例子,两个对象的交换函数(C++中可以轻易实现):
public class Swap {  
    public static void main(String[] args) {  
        ObjectSample o1 = new ObjectSample("hello");  
        ObjectSample o2 = new ObjectSample("你好");  
        System.out.println("before swap o1:"+o1.getTitle()+" o2:"+o2.getTitle());  
        Swap.swapObject(o1, o2);  
        System.out.println("after swap o1:"+o1.getTitle()+" o2:"+o2.getTitle());  
    }  
    static void swapObject(ObjectSample o1, ObjectSample o2){  
        ObjectSample temp = new ObjectSample("temp");  
        temp = o1;  
        o1 = o2;  
        o2 = temp;  
    }  
}  
 
class ObjectSample{  
    private String title;  
      
    ObjectSample(String title){  
        this.title = title;  
    }  
      
    public String getTitle(){  
        return title;  
    }  
}


输出结果:
before swap o1:hello o2:你好 
after swap o1:hello o2:你好


java在交换程序中并没有交换两个对象的值,交换的是两个对象的拷贝,不能实现让对象参数引用一个新对象,究其原因还是因为java是采用了值传递而非引用传递。

还有不少和以前自己接触的观点不一样的地方,当然需要借鉴的吸收并且经过自己的实践来辨别。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: