最近去面试,有一个面试官问到 java 中参数传递的问题,感觉自己对于这一块还是理解的不够深。今天我们就一起来学习一下 Java 中的接口和抽象类。下面是本文的目录大纲:
一 . 什么是按值传递,什么是按引用传递
二 . java 中的参数传递是按值传递还是按引用传递
三.总结
若有不正之处,请多多谅解并欢迎批评指正,不甚感激。
一 . 什么是按值传递,什么是按引用传递
按值调用 (call by value) : 在参数传递过程中,形参和实参占用了两个完全不同的内存空间。形参所存储的内容是实参存储内容的一份拷贝。
按值传递在基本数据类型数据传递中比较好理解,测试代码如下:
- public class test {
- public static void main(String[] args) {
- int age = 0;
- System.out.println("before change age=" + age);
- change(age);
- System.out.println("after change age=" + age);
- }
- public static void change(int a) {
- a = 20;
- }
- }
运行结果:
before change age=0after change age=0
这个结果相信很多朋友已经猜到:因为在 main 方法中调用 change(age) 时,真正传递给 change 方法的参数只是 age 的一个副本,所以修改这个副本,并不能修改原来 age 的值。
按引用调用:在参数传递的过程中,形参和实参完全是同一块内存空间,两者不分彼此。
例如:
- main()
- {
- int a=0;
- func(&a);
- printf("%d\n",a);
- }
- func(int *b)
- {
- *b=10;
- }
咳咳,这貌似是 C 语言的按引用传递。java 的安引用传递写不出来。
二. java 中的参数传递是按值传递还是按引用传递
在下结论之前,我们还是看一个例子:
- public class PassByValue {
- private String name;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- @Override public String toString() {
- return "PassByValue [name=" + name + "]";
- }
- public static void main(String[] args) {
- PassByValue myDear = new PassByValue();
- myDear.setName("dontKnow");
- String mylove = "dontKnow";
- int herAge = 0;
- System.out.println("myDear name=" + myDear.getName());
- System.out.println("myLove =" + mylove);
- System.out.println(herAge);
- stringChange(mylove, myDear, herAge);
- System.out.println("============================================================");
- System.out.println("myDear name=" + myDear.getName()) System.out.println(mylove);
- System.out.println(herAge)
- }
- public static void stringChange(String a, PassByValue b, int age) {
- a = "gaoshan"; //这一句相当于a=new String("gaoshan")
- b.setName("gaoshan");
- age = 20;
- }
- }
运行结果如下:
myDear name=dontKnowmyLove =dontKnow0============================================================myDear name=gaoshanmyLove =dontKnow0
我们发现,myDear 中的name属性通过 stringChange()方法改变了,myLove的值并没有改变。
这里有一个疑问:myDear 和 mylove都是引用数据类型,为什么 myDear 的属性值会改变,而mylove没有改变呢?
其实原因在注释中已经说了:在 stringChange 方法中,a="gaoshan"; 这一句等价于 a=new String("gaoshan"),实际上a作为数据引用发生了改变,指向了一个新的内存地址,而 myDear 作为数据引用,并没有发生改变,仍然指向main方法中 myDear 所指向的对象。
三. 总结在java中,不存在按引用调用,因为在参数传递过程中,不管传递的是基本数据类型的变量,还是对象的引用,其实都是传递的一个副本。
在上面的例子中,myDear 所指向的对象之所以会发生改变,是因为在 stringChange 方法中,通过 myDear 的副本b对 myDear 所指向的对象进行操作,改变了对象属性,但是
myDear 本身作为对象引用并没有发生改变。而 myLove 没有发生改变是因为在 stringChange 方法中直接改变了 myLove 副本a的值,并没有对 myLove 所指向的对象进行修改,所以我们看到 main 方法中的 myLove 所指向的对象并没有发生改变
本文参考
java 参数传递(超经典):http://blog.sina.com.cn/s/blog_4b622a8e0100c1bo.html
来源: http://www.bubuko.com/infodetail-2446281.html