前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >【Java】Java中是值传递还是引用传递的?

【Java】Java中是值传递还是引用传递的?

作者头像
哈__
发布2024-04-08 21:20:21
发布2024-04-08 21:20:21
29700
代码可运行
举报
文章被收录于专栏:哈哈熊哈哈熊
运行总次数:0
代码可运行

对于Java的初学者来说值传递和引用传递是一个容易混淆的概念,很多时候调用方法传入参数运行方法后的结果与自己享的不一致。那么Java到底是如何传参的呢?

简介

  1. 值传递
    • 在值传递中,函数接收到的是参数的值的副本,而不是参数本身。
    • 当你向函数传递一个参数时,函数会创建一个新的变量,并将传递给函数的值复制到这个新变量中。
    • 这意味着在函数内部对参数的修改不会影响到函数外部的原始值。
    • 值传递常见于基本数据类型(如整数、浮点数、布尔值等)的传递。
  2. 引用传递
    • 在引用传递中,函数接收到的是参数的引用(地址)而不是参数的值的副本。
    • 这意味着在函数内部对参数的修改会影响到函数外部的原始值。
    • 引用传递常见于复杂数据类型(如数组、对象、类实例等)的传递。
    • 多数情况下,引用传递可以节省内存空间,并且可以避免复制大量数据。

代码展示

有了基本的概念之后请看下面一段代码

代码语言:javascript
代码运行次数:0
复制
public static void main(String[] args) {
        int a = 10;
        int b = 20;
        swap(a,b);
        System.out.println("main函数中a="+a);
        System.out.println("main函数中b="+b);
    }
    public static void swap(int a,int b){
        int c = a;
        a = b;
        b = c;
        System.out.println("swap函数中a="+a);
        System.out.println("swap函数中b="+b);
    }

你是否认为在main方法中输出的a是20,b是10?请看输出结果。

很可惜,答案是原数值并没有交换,那么这是为什么呢? 

原理分析

在Java当中一个一个方法的调用都是一个入栈的过程,main方法首先入栈,当调用了swap方法的时候swap方法入栈,此时主函数传给swap函数的a和b都会被在swap方法中拷贝出一个副本出来,副本的值的交换不影响主函数中a和b的值。

 基本类型的int我们明白了之后我们看下面的一个例子。

代码语言:javascript
代码运行次数:0
复制
class Student{
    public String name;
    public int age;
    public Student(){}
    public Student(String name,int age){
        this.name = name;
        this.age = age;
    }
}
代码语言:javascript
代码运行次数:0
复制
 public static void main(String[] args) {
       Student s1 = new Student("张三",18);
       Student s2 = new Student("李四",20);
       swap(s1,s2);
       System.out.println(s1.name+"的年龄是"+s1.age);
       System.out.println(s2.name+"的年龄是"+s2.age);
    }
    public static void swap(Student s1,Student s2){
        int age = s1.age;
        s1.age = s2.age;
        s2.age = age;
    }

请看结果。

结果是否与你想的一样?你可能会想,不是副本进行交换不影响主函数当中变量的值吗?为什么打印的年龄是交换的了,是不是博主拿出一个瞎打印的结果来骗你了?不不不,请看我的分析。

 在Java当中我们new出来的对象是保存在堆区的,每一个对象有自己的地址,当我们在main方法中定义出s1和s2的时候,s1和s2会指向堆区当中他们new出来的对象,之后我们在调用swap方法,s1和s2的副本同样的指向到了堆区当中的s1和s2对象,那么在这个时候我们进行age的交换的时候就会影响到堆区当中的对象从而影响主方法中的对象。如果我们执行下边的代码。你觉得会改变年龄的结果吗?

代码语言:javascript
代码运行次数:0
复制
 public static void swap(Student s1,Student s2){
       Student s = s1;
       s1 = s2;
       s2 = s;
    }

答案是不会的,因为我们打印的是main方法中的s1和s2对象,swap方法中虽然执行了交换操作,但也仅仅是把swap方法中的s1指向了堆区当中的s2,把swap方法中的s2指向了堆区中的s1,没有对堆区对象做出影响。

结论

在Java中是按照值传递的方式,只不过参数是不同的类型可能会出现不同的结果。

希望我的解答能够为您提供帮助,喜欢的话希望给博主一个关注

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档