Java的对象是采用值传递还是引用传递?

来源:互联网 发布:什么是java框架 编辑:程序博客网 时间:2024/05/17 15:35

关于Java中的值传递我一开始是有点搞混的

值传递表示传递的是调用者的值
引用调用表示传递的是调用者提供的变量地址

所以重新再梳理一下

package Test;public class Test {    public static void main(String[] args){        Test test = new Test();        Student stu_a = test.new Student("Bob");        Student stu_b = test.new Student("Jerry");        double regular = 86; //平时成绩        double examining = 90; //考试成绩           System.out.println("\nTest1--------------------------------------------------");        System.out.println("Before regualr, examining: "+regular+", "+examining);        stu_a.setGrades(regular, examining);        System.out.println("After regualr, examining: "+regular+", "+examining);        System.out.println("\nTest2--------------------------------------------------");        System.out.println("Before stu_a Grades: "+stu_a.getGrades());        Awarded(stu_a);        System.out.println("After stu_a Grades: "+stu_a.getGrades());        System.out.println("\nTest3--------------------------------------------------");        System.out.println("Before stu_a = "+stu_a.getName());        System.out.println("Before stu_b = "+stu_b.getName());        swap(stu_a, stu_b);        System.out.println("After stu_a = "+stu_a.getName());        System.out.println("Bfter stu_b = "+stu_b.getName());    }    public static void swap(Student x, Student y){        Student temp = x;        x = y;        y = temp;        System.out.println("方法结束 x = "+x.getName());        System.out.println("方法结束 y = "+y.getName());    }    public static void Awarded(Student x){        x.add(20);        System.out.println("方法结束Grades: "+x.getGrades());    }    class Student{        private String name;        private double grades;        Student(String name){            this.name = name;        }        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public double getGrades() {            return grades;        }        public void setGrades(double x, double y) {            x *= 0.3;            y *= 0.7;            System.out.println("方法结束 x,y:"+x+", "+y);            grades= x + y;        }        public void add(double awarded){            grades += awarded;        }    }}

测试结果如下:
这里写图片描述

测试一、

double regular = 86; //平时成绩double examining = 90; //考试成绩   ......stu_a.setGrades(regular, examining);......
public void setGrades(double x, double y) {            x *= 0.3;            y *= 0.7;            System.out.println("方法结束 x,y:"+x+", "+y);            grades= x + y;        }

不必理睬这个方法的具体实现,在方法调用后regular还是86,examining还是90
其中具体执行过程是这样的:
1、x被初始化为regular值的一个拷贝
2、x = x*0.3
3、这个方法结束后,参数变量x不再使用,会被回收
4、y亦同理。
这里写图片描述

所以从头到尾regular变量都没有改变,传入的参数是它的一个拷贝。这个是值传递。

测试二

...Student stu_a = test.new Student("Bob");...Awarded(stu_a);...
public static void Awarded(Student x){        x.add(20);        System.out.println("方法结束Grades: "+x.getGrades());    }

从结果可以看到,传入对象stu_a,调用Awarded方法,stu_a的Grades值被改变了。
难道对象采用的就是引用传递吗?
不是!
看看具体执行的过程:
1、x被初始化为stu_a值的拷贝,x也指向Student对象,这里是一个对象的引用
2、add()方法应用于这个对象的引用,
3、方法结束后,参数变量x不再使用,回收。

这里写图片描述

之所以这里grades会改变,是因为调用new出来的这个Student对象add()方法,里面的grades被改变了。

接下来测试三、

 Student stu_a = test.new Student("Bob"); Student stu_b = test.new Student("Jerry"); ... swap(stu_a, stu_b);
public static void swap(Student x, Student y){        Student temp = x;        x = y;        y = temp;        System.out.println("方法结束 x = "+x.getName());        System.out.println("方法结束 y = "+y.getName());    }

最后结果看来,他们并没有交换!!!
来看看具体的执行过程:
1、swap方法的参数x和y被初始化两个对象引用的拷贝
2、x、y进行交换
3、方法结束,x、y不再使用,被回收。

交换前

这里写图片描述

交换后

这里写图片描述

所以至始至终都是x、y在交换,stu_a和stu_b没有交换

所以Java对象也是采用值传递的方式的。

0 0