java中为什么只存在值传递(以传入自定义引用类型为例) ...

打印 上一主题 下一主题

主题 906|帖子 906|积分 2718

java中只有值传递
为什么这么说?两个例子:
  1. public class Student {
  2.     int sage = 20;
  3.     String sname = "云胡不归";
  4.     public static void change(Student s1) {
  5.         s1.sname = "荀一";
  6.         s1.sage = 30;
  7.         System.out.println("-----------------------------------------------------------------");
  8.         System.out.println("change方法内 s1存储的堆空间地址 = " + s1);
  9.         System.out.println("修改时 s1.sname = " + s1.sname + " and s1.sage = " + s1.sage);
  10.         System.out.println("-----------------------------------------------------------------");
  11.     }
  12.     public static void main(String[] args) {
  13.         Student s = new Student();//此处的s是引用类型 实在栈空间开辟的一块空间,存储一个堆空内的地址 假设s指向堆空间的第一个Student对象
  14.         System.out.println("main方法内 s存储的堆空间地址 = " + s);
  15.         System.out.println("创建时 s.sname = " + s.sname + " and s.sage = " + s.sage);
  16.         change(s);//值传递的含义在于 将 s存储的地址复制一份 传入函数,使得函数内的形参s1存储地址和s相同 此时s1和s同时指向第一个Student对象
  17.         System.out.println("修改后 s.sname = " + s.sname + " and s.sage = " + s.sage);
  18.     }
  19. }
  20. //打印结果:
  21. main方法内 s存储的堆空间地址 = com.iweb.test.Student@1b6d3586
  22. 创建时 s.sname = 云胡不归 and s.sage = 20
  23. -----------------------------------------------------------------
  24. change方法内 s1存储的堆空间地址 = com.iweb.test.Student@1b6d3586
  25. 修改时 s1.sname = 荀一 and s1.sage = 30
  26. -----------------------------------------------------------------
  27. 修改后 s.sname = 荀一 and s.sage = 30
  28. //上述打印结果的含义:在栈空间有两块空间存储着一模一样的堆内存地址 无论修改哪一个都会影响它们指向的Student对象的属性
  29. //当然现在无法证明 栈空间是不是的确有两块空间存储着一模一样的堆内存地址 抑或是 只有一块栈内存,s1和s一起在用,因此引入下一个例子
复制代码
在change方法中再加上一句s1 = new Student();
  1. public class Student {
  2.     int sage = 20;
  3.     String sname = "云胡不归";
  4.     public static void change(Student s1) {
  5.         s1 = new Student();//使得栈空间s1存储一个新的堆内存地址 指向一个新的Student对象
  6.         s1.sname = "荀一";
  7.         s1.sage = 30;
  8.         System.out.println("-----------------------------------------------------------------");
  9.         System.out.println("change方法内 s1存储的堆空间地址 = " + s1);
  10.         System.out.println("修改时 s1.sname = " + s1.sname + " and s1.sage = " + s1.sage);
  11.         System.out.println("-----------------------------------------------------------------");
  12.     }
  13.     public static void main(String[] args) {
  14.         Student s = new Student();//此处的s是引用类型 实在栈空间开辟的一块空间,存储一个堆空内的地址 假设s指向堆空间的第一个Student对象
  15.         System.out.println("main方法内 s存储的堆空间地址 = " + s);
  16.         System.out.println("创建时 s.sname = " + s.sname + " and s.sage = " + s.sage);
  17.         change(s);//值传递的含义在于 将 s存储的地址复制一份 传入函数,使得函数内的形参s1存储地址和s相同 此时s1和s同时指向第一个Student对象
  18.         System.out.println("修改后 s.sname = " + s.sname + " and s.sage = " + s.sage);
  19.     }
  20. }
  21. //打印结果:
  22. main方法内 s存储的堆空间地址 = com.iweb.test.Student@1b6d3586
  23. 创建时 s.sname = 云胡不归 and s.sage = 20
  24. -----------------------------------------------------------------
  25. change方法内 s1存储的堆空间地址 = com.iweb.test.Student@4554617c
  26. 修改时 s1.sname = 荀一 and s1.sage = 30
  27. -----------------------------------------------------------------
  28. 修改后 s.sname = 云胡不归 and s.sage = 20
  29. //修改了栈空间内s1中存储的地址后对s没有任何影响 由此可见 s1和s在栈空间内占据两块独立的空间
复制代码
以上两个例子可以得出 引用类型传入change()方法的方式是值传递,是将地址复制了一份作为change()的参数
如果是引用传递 则 s1 和 s 应该是同一片栈空间 s1 = new Student()后,相当于也进行了 s = new Student() 的操作 change(s)调用后,对象的属性依旧会被修改

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

伤心客

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表