Born to be proud
7/6
2017

Java值传递与引用传递

Java值传递

指的是在方法调用时,传递的参数是按值的拷贝传递。此时内存中存在两个相等的基本类型,即实际参数和形式参数,后面方法中的操作都是对形参这个值的修改,不影响实际参数的值.

public class ParamTest {
    public static void main(String[] args) {
        int price = 5;
        doubleValue(price);
        System.out.print(price);    //【输出结果】: 5
    }

    public static void doubleValue(int x) {
        x = 2 * x;
    }
}

过程解析

  • x被初始化为price值的一个拷贝,即5
  • x乘以2后等于10。但是price没有变化,依然是5
  • doubleValue执行完后,参数变量不再使用

zhichuandi

Java引用传递

指的是在方法调用时,传递的参数是按引用进行传递,也就是变量所对应的内存空间的地址。在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象.

class Student {
    private float score;
    public Student(float score) {
        this.score = score;
    }
    public void setScore(float score) {
        this.score = score;
    }
    public float getScore() {
        return score;
    }
}

public class ParamTest {
    public static void main(String[] args) {
        Student stu = new Student(80);
        raiseScore(stu);
        System.out.print(stu.getScore());    //【运行结果】:90
    }

    public static void raiseScore(Student s) {
        s.setScore(s.getScore() + 10);
    }
}

过程解析

  • s被赋予stu值的拷贝,这里是一个对象的引用
  • raiseScore方法应用于这个应用。s和stu指向同一对象,该对象的分数增加了10
  • raiseScore方法结束后,s不再使用,stu指向的那个对象分数增加了10

yinyongchuandi

为什么说Java没有引用传递

class Student {

    private float score;

    public Student(float score) {
        this.score = score;
    }

    public void setScore(float score) {
        this.score = score;
    }

    public float getScore() {
        return score;
    }
}

public class ParamTest {
    public static void main(String[] args) {
        Student a = new Student(0);
        Student b = new Student(100);

        System.out.println("交换前:");        
        System.out.println("a的分数:" + a.getScore() + "--- b的分数:" + b.getScore());        //【运行结果】:a的分数:0.0--- b的分数:100.0

        swap(a, b);

        System.out.println("交换后:");
        System.out.println("a的分数:" + a.getScore() + "--- b的分数:" + b.getScore());        //【运行结果】:a的分数:0.0--- b的分数:100.0
    }

    public static void swap(Student x, Student y) {
        Student temp = x;
        x = y;
        y = temp;
    }
}

可以看出,上述代码运行后,a,b并没有实现交换。

过程解析

swap1
swap2
swap3

从这个过程中可以看出,严格来讲,Java采用的不是引用调用。实际上,对象引用进行的是值传递,只不过是传递的对象的地址。

Java中引用传递更类似 C++ 中指针作为参数. C++ 中指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已.

总结一下java中方法参数的使用情况:

  • 一个方法不能修改一个基本数据类型的参数(即数值型和布尔型)
  • 一个方法可以改变一个对象中变量的值
  • 一个方法不能让对象参数引用一个新的对象