黑马程序员技术交流社区

标题: 函数参数传递问题 [打印本页]

作者: kj1989    时间: 2014-4-3 15:04
标题: 函数参数传递问题
本帖最后由 kj1989 于 2014-4-5 20:51 编辑

当一个对象被当做参数传递给一个方法后,此方法可改变这个对象的属性,并可以反会变化后的结果,那么这里到底是值传递还是引用传递,此外两种传递的内在机制和区别是什么?
作者: 黄泉    时间: 2014-4-3 15:21
java中函数传递参数的方式都是   『传值』,这是最根本的。   
      对于基本型变量如int、float等来说,传递的是变量的内容,函数中的产生一个新的变量来接收参数的值,它们两个是两个内容一样的   『不同变量』     ,所以在函数中改变不会影响到原来的变量。   
  对于参数是对象来说,传递的是对象引用的一个副本,也就是说,函数中产生了一个引用变量,这个引用变量的值和作为参数传过来的那个变量的值是一样的,这两个不同的变量指向内存中同一个地址,即同一个对象。那么此时就有两种情况,假设a为函数中的接收参数的变量:   
     1.当执行如a=其他对象,a=new等赋值操作时,实际上是将a指向新的位置,那么函数外的原值不改变。   
     2.如果在函数中执行的是对a的成员变量的操作,或者调用对象中修改成员变量的函数,那么就改变了原值。   
   public       class       Test{         
      public       static       void       main(String[]       args){         
      StringBuffer       a=new       StringBuffer("A");         
      StringBuffer       b=new       StringBuffer("B");         
      operate(a,b);         
      System.out.println(a+","+b);         
          }         
      public       static       void       operate(StringBuffer       x,       StringBuffer       y){         
          x.append(y);         
          y=x;         
      }         
      }              
  答案:AB,B  
y=x;     只是表示y和x都指向同一个对象,但是你并没有对y原先所指向的对象作改变,因此实参b所指向的对象也就没有改变,输出当然是B;这个和你在c/c++中传指针是一样的道理,你在函数中改变指针变量本身的值并不会改变指针指向对象的值。
作者: y200745    时间: 2014-4-3 15:26
首先明确一下两种传递的定义:
值传递:是对所传递参数进行一次副本拷贝,对参数的修改只是对副本的修改,函数调用结束,副本丢弃,原来的变量不变(即实参不变)
引用传递:参数被传递到函数时,不复制副本,而是直接将参数自身传入到函数,函数内对参数的任何改变都将反映到原来的变量上。

java中的引用更像C++中的指针,当我们定义一个对象时(比如Person p=new Person()),定义的对象实例会放到java堆中,而变量p(即引用)会放到java栈中,p指向堆中的Person对象实例。

在java中,只有值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。引用的来源的值是不变的。但引用来后,作为内容的值是可以改变的。
作者: 帅哥哥    时间: 2014-4-3 15:29
其实想彻底明白这类问题,把程序里面的内容在内存中是怎么存储的搞明白,哪些在堆区,哪些在栈区,哪些在方法区(静态区),我觉着这样就都清楚了

2.png (85.75 KB, 下载次数: 9)

2.png

作者: 张治国    时间: 2014-4-3 17:17
是值得传递。
java语言中只有值传递参数,对一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用,对象的内容可以在被调用的方法中改变,但对象的引用是永远改变不了的。
作者: Engle    时间: 2014-4-3 21:17
是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。

Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。

    如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值.
    如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2