今日做了一个项目,涉及到JAVA对于参数传递的方式,平时一直认为JAVA的参数传递方式为值传递,就是把传递的对象拷贝到新的对象去再进行使用,从而不影响原来对象的值,但是,我发现结果却不是这样:
class Apple{ int num; } public class Test01 { public test01(Apple a) { ss(a); System.out.println(a.num); } public void ss(Apple a) { a.num=100; } public static void main(String[] args) { Apple apple = new Apple(); apple.num = 1; Test01 sTest01 = new Test01(apple); } }
这是我碰到问题的简化说明,按照一贯JAVA为值传递的思想,我以为输出的结果会是1,结果却为100,这是为什么呢?
难道JAVA也能进行参数传递么?我进行了官方文档查阅,得出的却是JAVA的确为值传递的方式。
我接着上网百度了一下许多博客得出了以下的结论:
1.首先,八种基本数据类型分别是:int、short、float、double、long、boolean、byte、char;
它们的封装类分别是:Integer、Short、Float、Double、Long、Boolean、Byte、Character。
2.原始数据类型在传递参数时都是按值传递,封装类都是按引用传递(还是按值传递的范畴)。
这一句话很重要,重点解释一下:首先,八种原始数据的对象是直接存储值,而封装类的对象存储的不是值,是值得引用,举个例子,好比我把一本书放在你那,你就是存储书的对象,但是你并不把书放在你的手里,而是放在一个带锁的箱子里,你的手中拿着锁即(值得引用),当传参时,八种基本类型直接把值复制传递过去,而封装类却是把引用复制传递过去,好比你复制了一把钥匙给别人,那么别人当然有改动箱子中存的书的权利啦。
验证举例:
public class Test02 { int a=10; Integer A=new Integer(100); public Test02() { showValue(); swap(a,A); showValue(); } public void swap(int a,Integer A) { a++;A++; } public void showValue() { System.out.println("a:"+a+" A:"+A); } public static void main(String[] args) { new Test02(); } }
上面的运行后结果却为改变,按上面所说的,A值应该增加一,这是因为A++;相当于A=A+1;一旦使用了赋值=,这已经改变了对象的引用,即该对象的引用不再指向先前那一个引用,而是在内存中开辟新的存储,新的引用。
验证举例:
class Banana { int a=10; } public class Test02 { public Test02(Banana banana) { banana.a++; } public static void main(String[] args) { Banana banana = new Banana(); System.out.println(banana.a); new Test02(banana); System.out.println(banana.a); } }
上述运行过后a的值发生了改变,因为对于对象banana的引用在Test02中未发生改变,故以上说明成立。
总结:JAVA的参数传递方式确实是以值传递的方式进行,其中基本类型是值传递,而其他是引用传递。