当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

参考解答

java 中方法传参只有值传递。

首先明确一点,java中的方法调用时,会在方法执行之前把这些参数创建出来,为这些参数分配空间、而每个参数的值,来自于实参的拷贝。例如:

基本类型:

public static void foo(int i){
}
public static void main(String[] args) {
   /* 
      将a的值10拷贝一份,传递给方法参数i
      a和i是完全不同的变量,占用不同的内存空间 
      即使将int i的参数名改为a也一样
   */
   int a = 10;
   foo(a);
}

引用类型:

public static void foo(User u){
}
public static void main(String[] args) {
   /* 
      将x的引用值拷贝一份,传递给方法参数u
      x和u是完全不同的变量,占用不同的内存空间
      即使将User u的参数名改为x也一样 
   */
   User x = new User();
   foo(x);
}

更详细的过程分析,请看下面的例子:

例1:

public static void main(String[] args) {
  Cat c1 = new Cat();
  c1.name = "小黑";
  foo(c1);
  System.out.println(c1.name);
}

public static void foo(Cat c2) {
  c2 = new Cat();
  c2.name = "小白";
}

执行过程分析如下:

  1. main方法中执行new Cat() 在堆中分配内存(假设地址为0001),初始化name=null,接下来将引用地址0001赋值给main方法中的c1变量

  2. 根据c1变量,引用到堆中0001处的Cat对象,修改name=小黑

  3. 接下来调用foo方法,将main中c1变量的值(0001),赋值给foo方法中的c2变量,这里是传值,c1和c2只是引用值一样,引用了同一个堆对象,而它们是独立的变量,占用不同的内存空间

  4. 在foo方法中执行new Cat() 会在堆中新分配一块内存(假设地址为0002),初始化name=null,并将引用地址0002赋值给foo中的c2变量,这时c1不会受到任何影响,仍是0001

  5. 根据c2变量,引用到堆中0002处的Cat对象,修改name=小白

  6. 返回main方法,这时c1变量仍然引用的是0001,因此打印c1.name还是小黑

但 c++ 中是分值传递和引用传递的:

例2 C++值传递:

#include <stdio.h>

void swap(int i, int j) {
   int t = i;
   i = j;
   j = t;
}

int main() {
   int a = 23, b = 47;
   printf("Before. a: %d, b: %d\n", a, b);
   swap(a,b);
   printf("After.  a: %d, b: %d\n", a, b);
   return 0;
}

输出:

Before. a: 23, b: 47
After.  a: 23, b: 47

例3 C++引用传递:

#include <stdio.h>

void swap(int *i, int *j) {
   int t = *i;
   *i = *j;
   *j = t;
}

void main() {
   int a = 23, b = 47;
   printf("Before. a: %d, b: %d\n", a, b);
   swap(&a, &b);
   printf("After . a: %d, b: %d\n", a, b);
}

输出:

Before. a: 23, b: 47
After.  a: 47, b: 23

java中:

例4 java值传递(基本类型):

public static void swap(int a, int b) {
  int c = a;
  a = b;
  b = c;
}

public static void main(String[] args) {
  int a = 23;
  int b = 47;
  System.out.println("Before, a:" + a + " b:"+ b);
  swap(a,b);
  System.out.println("After, a:" + a + " b:"+ b);
}

输出:

Before, a:23 b:47
After, a:23 b:47

例5 java值传递(引用类型):

public static void swap(Integer a, Integer b) {
  Integer c = a;
  a = b;
  b = c;
}

public static void main(String[] args) {
  Integer a = new Integer(23);
  Integer b = new Integer(47);
  System.out.println("Before, a:" + a + " b:"+ b);
  swap(a,b);
  System.out.println("After, a:" + a + " b:"+ b);
}

输出仍是:

Before, a:23 b:47
After, a:23 b:47

results matching ""

    No results matching ""