本人初学java在学习到对象型参数传递时,对此感觉思维混乱。最终花了半天时间理清了思路,写了一个简单的程序来辅助理解和验证结论:
程序中定义了7个类的实例,进行改变和交换,观察其规律,从而理解对象型参数传递。
代码:
package demo;
class Time{
int a;
}
public class demo{
Time time1 = new Time();
Time time2 = new Time();
Time time3 = new Time();
Time time4 = new Time();
Time time5 = new Time();
Time time6 = new Time();
Time time7 = new Time();
public static void main(String[] args){
demo de = new demo();
de.time1.a = 1;
de.time2.a = 2;
de.time3.a = 3;
de.time4.a = 4;
de.time5.a = 5;
de.time6.a = 6;
de.time7.a = 7;
System.out.println("time改变前:");
System.out.println("time1.a="+de.time1.a);
System.out.println("time2.a="+de.time2.a);
System.out.println("time3.a="+de.time3.a);
System.out.println("time4.a="+de.time4.a);
System.out.println("time5.a="+de.time5.a);
System.out.println("time6.a="+de.time6.a);
System.out.println("time7.a="+de.time7.a);
System.out.println("time2的地址="+de.time2);
System.out.println("time3的地址="+de.time3);
System.out.println("time4的地址="+de.time4);
System.out.println("time5的地址="+de.time5);
System.out.println("time6的地址="+de.time6);
System.out.println("time7的地址="+de.time7);
de.change(de.time1);
de.swap1(de.time2,de.time3);
de.swap2(de.time4,de.time5);
de.swap3(de.time6,de.time7);
System.out.println("time改变后:");
System.out.println("time1.a="+de.time1.a);
System.out.println("time2.a="+de.time2.a);
System.out.println("time3.a="+de.time3.a);
System.out.println("time4.a="+de.time4.a);
System.out.println("time5.a="+de.time5.a);
System.out.println("time6.a="+de.time6.a);
System.out.println("time7.a="+de.time7.a);
System.out.println("time2的地址="+de.time2);
System.out.println("time3的地址="+de.time3);
System.out.println("time4的地址="+de.time4);
System.out.println("time5的地址="+de.time5);
System.out.println("time6的地址="+de.time6);
System.out.println("time7的地址="+de.time7);
}
void change(Time t1)
{
t1.a=11;
}
void swap1(Time t2, Time t3)
{
System.out.println("###########交换前t2.a="+t2.a);
System.out.println("###########交换前t3.a="+t3.a);
System.out.println("###########交换前t2的地址="+t2);
System.out.println("###########交换前t3的地址="+t3);
Time temp;
temp = t2;
t2 = t3;
t3 = temp;
System.out.println("###########交换后t2.a="+t2.a);
System.out.println("###########交换后t3.a="+t3.a);
System.out.println("###########交换后t2的地址="+t2);
System.out.println("###########交换后t3的地址="+t3);
}
void swap2(Time t4, Time t5)
{
System.out.println("###########交换前t4.a="+t4.a);
System.out.println("###########交换前t5.a="+t5.a);
System.out.println("###########交换前t4的地址="+t4);
System.out.println("###########交换前t5的地址="+t5);
Time temp = new Time();
temp = t4;
t4 = t5;
t5 = temp;
System.out.println("###########交换后t4.a="+t4.a);
System.out.println("###########交换后t5.a="+t5.a);
System.out.println("###########交换后t4的地址="+t4);
System.out.println("###########交换后t5的地址="+t5);
}
void swap3(Time t6, Time t7)
{
System.out.println("###########交换前t6.a="+t6.a);
System.out.println("###########交换前t7.a="+t7.a);
System.out.println("###########交换前t6的地址="+t6);
System.out.println("###########交换前t7的地址="+t7);
Time temp =new Time();
temp.a = t6.a;
t6.a = t7.a;
t7.a = temp.a;
System.out.println("###########交换后t6.a="+t6.a);
System.out.println("###########交换后t7.a="+t7.a);
System.out.println("###########交换后t6的地址="+t6);
System.out.println("###########交换后t7的地址="+t7);
}
}
运行结果:
time改变前:
time1.a=1
time2.a=2
time3.a=3
time4.a=4
time5.a=5
time6.a=6
time7.a=7
time2的地址=demo.Time@4f9fdc
time3的地址=demo.Time@18825b3
time4的地址=demo.Time@1632847
time5的地址=demo.Time@e95a56
time6的地址=demo.Time@29e357
time7的地址=demo.Time@ca470
###########交换前t2.a=2
###########交换前t3.a=3
###########交换前t2的地址=demo.Time@4f9fdc
###########交换前t3的地址=demo.Time@18825b3
###########交换后t2.a=3
###########交换后t3.a=2
###########交换后t2的地址=demo.Time@18825b3
###########交换后t3的地址=demo.Time@4f9fdc
###########交换前t4.a=4
###########交换前t5.a=5
###########交换前t4的地址=demo.Time@1632847
###########交换前t5的地址=demo.Time@e95a56
###########交换后t4.a=5
###########交换后t5.a=4
###########交换后t4的地址=demo.Time@e95a56
###########交换后t5的地址=demo.Time@1632847
###########交换前t6.a=6
###########交换前t7.a=7
###########交换前t6的地址=demo.Time@29e357
###########交换前t7的地址=demo.Time@ca470
###########交换后t6.a=7
###########交换后t7.a=6
###########交换后t6的地址=demo.Time@29e357
###########交换后t7的地址=demo.Time@ca470
time改变后:
time1.a=11
time2.a=2
time3.a=3
time4.a=4
time5.a=5
time6.a=7
time7.a=6
time2的地址=demo.Time@4f9fdc
time3的地址=demo.Time@18825b3
time4的地址=demo.Time@1632847
time5的地址=demo.Time@e95a56
time6的地址=demo.Time@29e357
time7的地址=demo.Time@ca470
结果分析:
值方面:time1.a改变,time6.a和time7.a交换; time2.a time3.a time4.a time5.a 没变。
地址方面:t2和t3交换,t4和t5交换;time的地址没变,t4和t5没变。
总结:java对象型参数传递,实际上也是值传递(这个值为对象的地址)
(1)对比swap1和swap3
t2和t3交换(传入的地址交换了)t2.a和t3.a交换(地址交换,指向的值由于地址交换而交换)
t6和t7没交换(地址没交换)t6.a和t7.a没交换(单独交换了彼此的值)
time2和time3没交换 (把传入的地址看做是值传递,和普通变量参数传递类似)
time6和time7交换 (通过传入的地址,把地址指向位置中的值交换了,与C++中的指针类似)
(2)对比swap1和swap2
属于我个人的一个疑惑点验证,占时和此文要阐述的问题无关,读者可以先忽略。