今日做了一个项目,涉及到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的参数传递方式确实是以值传递的方式进行,其中基本类型是值传递,而其他是引用传递。