找回密码
 立即注册
首页 业界区 业界 面试常考基础,Java传递方式--值传递

面试常考基础,Java传递方式--值传递

决台 2025-8-21 13:54:50
前言

这是一篇很基础的文章,有一天我突然想到Java中只有值传递,但是为什么在传递对象的时候,里面的值修改后,实参也会被修改,我就特意去了解了一下这些相关的知识。这一学,我发现我之前的一些了解是错误的,不只是是对Java传递参数理解有问题,对C++中这传递也是有问题的。因此我觉得我应该特地写一篇随笔,帮我理解,毕竟感觉真正的弄懂,是能够帮助别人理解。
正文

值传递

简单的基本类型

关于值传递基本类型我就不过多叙述了,感觉有点像水字数一样。
就简单举个例子过一下
  1. public class Main {
  2.      public static void change(int a){
  3.          a = 2;
  4.      }
  5.      public static void main(String[] args) {
  6.          int a = 1;
  7.          change(a);
  8.          System.out.println(a);
  9.     }
  10. }
复制代码
运行截图:
1.png

基本的数据类型都是这样的情况
传递引用类型

接下来来传递引用类型
现在说一下前言中说我在C++关于传递的错误理解
我一直以为,C++中的引用传递,传递的参数与实参指向同一个对象(这是对的),因此传递过去实际是实参的地址,后面我才发现我理解错了,实际形参就直接理解为就是实参的一个别名。
接下来说说我另一个理解错误的地方(这部分结合值传递引用类型讲解)
我过去的理解,值传递是不可能能够改变实参的,在Java中,我又发现好像可以改变耶,我就以为是不是我记错了,Java中的传递方式也是有两种,除了值传递,还有引用传递,我还以为我记错了,我特意上网查了一下,确实没有,我也特意弄懂了这一部分。
下面我将通过例子进行讲解
  1. class Student {
  2.     public int id;
  3.     public String name;
  4.     public Student(int id, String name) {
  5.         this.id = id;
  6.         this.name = name;
  7.     }
  8.     @Override
  9.     public String toString() {
  10.         return "Student{id=" + id + ", name='" + name + "'}";
  11.     }
  12. }
  13. public class Main {
  14.     public static void change1(Student student) {
  15.         student.id = 2;
  16.     }
  17.     public static void change2(Student student) {
  18.         student=new Student(2,"Bob");
  19.     }
  20.     public static void main(String[] args) {
  21.         Student student1 = new Student(1, "Alice");
  22.         Student student2 = new Student(1, "Alice");
  23.         System.out.println("student1改变前 " + student1);
  24.         System.out.println("student2改变前 " + student2);
  25.         change1(student1);
  26.         change2(student2);
  27.         System.out.println("根据change1方法改变后 " + student1);
  28.         System.out.println("根据change2方法改变后 " + student2);
  29.     }
  30. }
复制代码
在例子中我们定义了Student类用充当引用对象,方法change1相当于setter方法,改变形参对象内属性值;方法change2则是使更换指向对象。
运行截图:
2.png

最后方法change1根据使得实参对象内属性值发生改变,而方法change2却没用使得实参更换指向对象。
原因讲解:
change1(student1)
形参 student1 得到 假设地址为0xAAA 的拷贝。
student.id = 2; 是通过这份拷贝里的地址找到原对象,把 id 改成 2。
原对象确实被改了,因此 student1 打印出 Student{id=2, name='Alice'}。
change2(student2)
形参 student2 得到 假设地址为0xBBB 的拷贝。(因为是new Student()创建,执行两个完全独立的对象)
student = new Student(2,"Bob"); 只是 把这份拷贝里的地址改成了新对象 0xCCC,原来的 student2 仍指向 0xBBB,毫无变化。
所以 student2 打印依旧是 Student{id=1, name='Alice'}。
对应值传递引用对象,更换指向对象,例子很多,里面有很多很隐晦的,如对String赋值,由于String是不可变,用final修饰,看向在实现String更换值了,实际是更换了指向对象;还有Integer的自动装箱,这些例子我参考了一下这篇文章(https://blog.csdn.net/yiridancan/article/details/149813906)
结论


  • Java 中进行值传递,方法收到的永远是实参的一份拷贝,也可以说是副本,在传递基本类型时,是传递真正的数,对这份拷贝本身做任何重新赋值都不会影响原来的变量;在传递引用类型时,是传递的是对象地址的副本,而但通过拷贝里保存的对象地址去改对象内部字段是可以的。*

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

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