Java基础知识---关于值传递与引用传递
在我看的网上面试题目以及自身经历过得几次面试中,我都遇见了关于值传递与引用传递的问题,一度被这个问题搞得晕头转向的,所以上网查了一些资料,做了这样的一篇小总结。
一、什么是值传递
首先,我们来看一下下面这个简单的demo1
public class Demo1 {
public static void main(String[] args){
int a=99;
changeA(a);
System.out.println(a);
}
public static void changeA(int a){
a=100;
System.out.println(a);
}
}
执行demo1会得到什么样的结果呢?是100,100还是100,99呢?
答案是这样的:
为什么不是100,100呢?原来传递这些基础数据类型的时候,传递的参数并不是之间将参数的引用传递给调用的函数,
而是产生一个参数的复杂对象,也就是构建一个
参数的的副本,虽然我们在调用方法中修改了这个副
本对象的数据,但
是并不会影响传递进来之前的那个参数的值,所以简单的说传进来的a并不是main方
法中的a了。
二、什么是引用传递
接着,我们再来看一下下面的demo2
public class Demo2 {
public int age;
public static void main(String[] args){
Demo2 d=new Demo2();
d.age=100;
changeAge(d);
System.out.println(d.age);
}
public static void changeAge(Demo2 d){
d.age=1000;
}
}
这段代码的运行结果又是怎么样的呢?是100还是1000?
答案是这样的:
为什么是1000呢?这里碰见的就是我们的引用传递,应用传递顾名思义就是传递了这个参数的引用,在内存中我们新建了
一个对象,会在堆上创建一个内存地址来保存对象数据
之后获得这个对象地址值得引用,当我们传入对象参数的时候会传
入这个对象参数的引用,所以在函数中对这个引用对象进行修改的时候就会修改对应的地址位置上的数据,而
在主函数中
的对象也指向这个内存地址,所以结果主函数中的该对象也发生了变化。
三、一些特殊的情况
上面我们举例说明了说明是值传递和引用传递,那么这些传递还有比较特殊的情况,如下,我们在changAge方法中,在修
改之前添加了d=new Demo2()这样一句话,结果却变成了100,这是为什么呢?
其实道理也是一样的,当传入这个地址的引用之后,我们又进行了新建操作,这个时候d就从对主函数主地址值得引用改变到
了新的地址值得引用,这时候我们再进行修改的时候,就修改了是新的地址中的数据,而主函数中对应的那个地址内存却没有
发生变化,说到底,经过这个新建操作主函数的d和changeAge的d已经不是一个东西了。对于上述的情况在java中还是比较容
易碰到的,比如如下一段demo中所展示的:
public class Demo3 {
public static void main(String[] args){
String a="hello";
changeAge(a);
System.out.println(a);
}
public static void changeAge(String a){
a="nihao";
}
}
输出的结果如下:
产生上面这样结果的原因在于在java中对一String这类对象在具有不可变的特性,修改String对象的值实际上就是在字符串池新
建一个字符串,并获得到这个字符串的引用,与上面的新建例子类似的,主函数中的a与changeAge的a所指向的地址已经不相
同,所以修改changeAge中的String对象不会对主函数中的对象产生影响。
三、那些情况下是值传递那些情况下是引用传递
根据上面的例子,我得出一些总结:
1、基本数据类型都是值传递的。
2、类类型的大部分都是引用传递。
3、部分特殊的对象类如String,Integer等类由于特殊的内存处理方式导致看上去是值传递。