Java中没有引用传递只有值传递(在函数中)

java

◆传参的问题

  引用类型(在函数调用中)的传参问题,是一个相当扯的问题。有些书上说是传值,有些书上说是传引用。搞得Java程序员都快成神经分裂了。所以,我们最后来谈一下“引用类型参数传递”的问题。

  如下例子,假设现在要把刚才创建的那一坨字符串打印出来,我们会使用如下语句:

StringBuffer str = new StringBuffer();

System.out.println(str); //这个语句又是什么意思捏?这时候就两说了。

  第一种理解:可以认为传进函数的是str这个指针,指针说白了就是一个地址的值,说得再白一点,就是个整数。按照这种理解,就是传值的方式。也就是说,参数传递的是指针本身,所以是传值的。

  第二种理解:可以认为传进去的是StringBuffer对象,按照这种理解,就是传引用方式了。因为我们确实是把对象的地址(也就是引用)给传了进去。

  费了这么多口水,其实不论是传引用还是传值,都可以讲得通,关键取决于你是如何看待参数所传递的东西。这就好比量子力学中“光的波粒二象性”,如果你以粒子的方式去测量它,它看起来像粒子;如果你以波动的方式去观测它,它看起来像波动。

/**

* @description Java中没有引用传递只有值传递

*

* @author Alexia

* @date 2013-10-16

*

*/

class Person {

private String name;

private String sex;

public Person(String x, String y) {

this.name = x;

this.sex = y;

}

// 重写toString()方法,方便输出

public String toString() {

return name + " " + sex;

}

// 交换对象引用,这里的p1和p2是swapObject这个函数的变量(局部变量),

// p1、p2接收的就是传递进来的一个堆内存的地址,改变p1、p2的指向只是改变了这两个局部变量的指向。

// 实际的全局变量还是没变的

public static void swapObject(Person p1, Person p2) {

Person tmp = p1;

p1 = p2;

p2 = tmp;

}

// 交换基本类型

public static void swapInt(int a, int b) {

int tmp = a;

a = b;

b = tmp;

}

// 交换对象数组

public static void swapObjectArray(Person[] p1, Person[] p2) {

Person[] tmp = p1;

p1 = p2;

p2 = tmp;

}

// 交换基本类型数组

public static void swapIntArray(int[] x, int[] y) {

int[] tmp = x;

x = y;

y = tmp;

}

// 改变对象数组中的内容

public static void changeObjectArray(Person[] p1, Person[] p2) {

Person tmp = p1[1];

p1[1] = p2[1];

p2[1] = tmp;

// 再将p1[1]修改

Person p = new Person("wjl", "male");

p1[1] = p;

}

// 改变基本类型数组中的内容

public static void changeIntArray(int[] x, int[] y) {

int tmp = x[1];

x[1] = y[1];

y[1] = tmp;

x[1] = 5;

}

}

public class ByValueTest {

public static void main(String[] args) {

// 建立并构造两个对象

Person p1 = new Person("Alexia", "female");

Person p2 = new Person("Edward", "male");

System.out.println("对象交换前:p1 = " + p1.toString()); //Alexia female

System.out.println("对象交换前:p2 = " + p2.toString()); //Edward male

// 交换p1对象和p2对象

Person.swapObject(p1, p2);

// 从交换结果中看出,实际对象并未交换

System.out.println("对象交换后:p1 = " + p1.toString()); //Alexia female

System.out.println("对象交换后:p2 = " + p2.toString()); //Edward male

// 建立两个对象数组

Person[] arraya = new Person[2];

Person[] arrayb = new Person[2];

// 分别构造数组对象

arraya[0] = new Person("Alexia", "female");

arraya[1] = new Person("Edward", "male");

arrayb[0] = new Person("jmwang", "female");

arrayb[1] = new Person("hwu", "male");

System.out.println("对象数组交换前:arraya[0] = " + arraya[0].toString() + ", arraya[1] = "
        + arraya[1].toString()); //Alexia female,Edward male

System.out.println("对象数组交换前:arrayb[0] = " + arrayb[0].toString() + ", arrayb[1] = "
        + arrayb[1].toString()); //jmwang female,hwu male

// 交换这两个对象数组

Person.swapObjectArray(arraya, arrayb);

System.out.println("对象数组交换后:arraya[0] = " + arraya[0].toString() + ", arraya[1] = "
        + arraya[1].toString()); //Alexia female,Edward male

System.out.println("对象数组交换后:arrayb[0] = " + arrayb[0].toString() + ", arrayb[1] = "
        + arrayb[1].toString()); //jmwang female,hwu male

// 建立两个普通数组

int[] a = new int[2];

int[] b = new int[2];

// 给数组个元素赋值

for (int i = 0; i < a.length; i++) {

a[i] = i;

b[i] = i + 1;

}

System.out.println("基本类型数组交换前:a[0] = " + a[0] + ", a[1] = " + a[1]); //0,1

System.out.println("基本类型数组交换前:b[0] = " + b[0] + ", b[1] = " + b[1]); //1,2

// 交换两个基本类型数组

Person.swapIntArray(a, b);

System.out.println("基本类型数组交换后:a[0] = " + a[0] + ", a[1] = " + a[1]); //0,1

System.out.println("基本类型数组交换后:b[0] = " + b[0] + ", b[1] = " + b[1]); //1,2

// 改变对象数组的内容

Person.changeObjectArray(arraya, arrayb);

System.out.println("对象数组内容交换并改变后:arraya[0] = " + arraya[0].toString() + ", arraya[1] = "
        + arraya[1].toString()); //Alexia female,wjl male

System.out.println("对象数组内容交换并改变后:arrayb[0] = " + arrayb[0].toString() + ", arrayb[1] = "
        + arrayb[1].toString()); //jmwang female,Edward male

// 改变基本类型数组的内容

Person.changeIntArray(a, b);

System.out.println("基本类型数组内容交换并改变后:a[0] = " + a[0] + ", a[1] = " + a[1]); //0,5

System.out.println("基本类型数组内容交换并改变后:b[0] = " + b[0] + ",b[1] = " + b[1]); //1,1

}

}

   说明:不管是对象、基本类型还是对象数组、基本类型数组,在函数中都不能改变其实际地址但能改变其中的内容。

  【相当于传递进来的栈内存的值,栈内存只存放地址和基本数据内容,是不可在函数中改变的】

以上是 Java中没有引用传递只有值传递(在函数中) 的全部内容, 来源链接: utcz.com/z/392817.html

回到顶部