论坛首页 Java企业应用论坛

关于程序语言中的参数传递

浏览 2644 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-09-19   最后修改:2009-09-19

  关于程序语言中的值传递问题很是让人迷惑,在此,更具自己的理解,以C语言和java语言为例来阐述一下参数传递。
    c语言中,参数传递方式有有三种:值传递,指针传递以及引用传递。
    java语言中有两种:值传递以及引用传递。
    java语言中的参数传递和c语言中的参数传递机制不太一样,即使传递方式名称一样可是最后效果还是有区别!
    对于值传递,它们的效果都是一样的,只是java中只允许对基本数据类型进行值传递;而在c语言中,值传递针对的数据类型可以使除了数组之外的所有类型(c语言中的数组类型参数传递都是指针传递)!
    由于在java中没有指针的概念,因此java中的对出了基本数据类型之外的传递都是引用传递,但是这里我发现一个小的区别和c语言中的区别:
比如下面的例子:
package test;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PersonT {
  static final Log log = LogFactory.getLog(PersonT.class);
    public void change(Person p) {
        p.name = "mary";
        p.age = 20;
    }

    public void changeInt(int i) {
        i = 8;
    }
//有返回值的方法
    public Person change1(Person p){
//新建对象,name为tpm,age为22
       p = new Person("tom",22);
       return p;
    }
//没有返回值的方法
    public void change1(Person p){
//新建对象,name为tpm,age为22
       p = new Person("tom",22);
      
    }
    public static void main(String[] args) {
        PersonT t = new PersonT();
        Person p = new Person("john", 18);
        Person p1 = p;
        log.info(p1.age);
//通过方法改变对象属性值
        t.change(p1);
        log.info(p1.age);
        log.info("传回来的值指向是否一致:" + p.equals(p1));
//通过方法改变整数值
        int i = 10;
        log.info("i值为:" + i);
        t.changeInt(i);
        log.info("i值为:" + i);
//新建一对象,改变对象值
      p=  t.change1(p);
        log.info("传回来的值指向是否一致:" + p.equals(p1));
        log.info(p.age);
    }

}
输出结果:
2009-09-19 10:02:41 [日志信息] 18
2009-09-19 10:02:41 [日志信息] 20
2009-09-19 10:02:41 [日志信息] 传回来的值指向是否一致:true
2009-09-19 10:02:41 [日志信息] i值为:10
2009-09-19 10:02:41 [日志信息] i值为:10
2009-09-19 10:02:41 [日志信息] 传回来的值指向是否一致:false
2009-09-19 10:02:41 [日志信息] 22//方法有返回值的时候的
2009-09-19 10:02:41 [日志信息] 20//方法没有有返回值的时候的
大家可以看到:当你在一个方法中创建一个对象,并把这个对象赋值给传递的参数时,如果在c语言中(前提是引用传递),不论是否又返回值,应该都会修改其指向的内存单元,但是在java中只有当此方法又返回值时候才修改其指向的内存单元,否则,其指向的内存单元不会改变即使赋值不起作用!但是但你在方法中修改其属性时却可以,我想这肯定是它们在java内部做了一些处理!
   它的作用很明显:不允许你在方法体中对参数对象重新赋值,只允许你在方法体中对参数对象的属性进行修改!

   发表时间:2009-09-19   最后修改:2009-09-19
"java语言中有两种:值传递以及引用传递。"
这句话还是不要再说了,虽然有过C经历的阁下还是可以区分所谓的值传递和引用传递,
但我记得james gosling(不知道这个拼对没有)说过,(事实上也确实是这样),java中都是pass by value ,即传值,关键要弄清,传的是什么值。只要记住都是pass by value,其实就可以搞清楚了,没必要整那么复杂
0 请登录后投票
   发表时间:2009-09-19  
我还是觉得把他们区别开叫更好一些,你说的也对,都是传值,但是一个传递的是值的拷贝,另一个传递的是值所在内存区域的地址,为了表达出这种区别,程序中使用了值传递和引用传递;我想java语言的底层实现也是C语言;还是个人看法的习惯不同,就是这个值的理解不同,如果你认为是字节信息那么可定都是一样的。
0 请登录后投票
   发表时间:2009-09-19  
你说的也对 但我觉得还是有些许问题(如果我没理解错的话)
“(在一个方法中创建一个对象....)但是在java中只有当此方法又返回值时候才修改其指向的内存单元,否则,其指向的内存单元不会改变即使赋值不起作用!”
从结果来看,这是对的,但实际上不是这样,即便传的是引用,也就是阁下说的“传递的是值所在内存区域的地址”,其实也是传的该值的拷贝,因此如果调用传进来的参数(某个对象的引用)的方法,那么这个拷贝跟原引用指向的是同一个对象实体,因此不用返回值就可以改变该对象,但如果新建对象,比如在方法中arg=new XXXX();那么该参数的值已经变成新建的对象的引用,跟传进来的那个原先的引用一点关系也没有了,他进行的操作,比如arg.setXXX();改变的是新建的对象的属性,所以,如果不返回,那么这个方法内的局部对象变量将没有意义,看起来像是这个操作不起作用
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics