JavaDog程序狗
JavaDog程序狗
发布于 2025-06-05 / 20 阅读
0
0

【Java】值传递还是引用传递?女朋友都会的基础问题,你竟然还模糊!

前言

🍊缘由

值传递和引用传递,傻傻分不清楚?

🐣闪亮主角

大家好,我是JavaDog程序狗。今天咱们来唠唠Java里一个让新手头疼,老手也偶尔会迷糊的事儿——值传递和引用传递

现在,我就结合实际案例,用大白话给你分析分析,让你一次性搞懂:啥是值传递?啥是引用传递?为啥Java里只有值传递?哪些情况容易让人误以为是引用传递?

😈你想听的故事

狗哥之前带过一个小徒弟,有一次他写了个方法,想在方法里修改传入的对象。结果发现,对象在方法里改了,出了方法又变回原样了。小徒弟一脸懵圈地跑来问我:“老狗,这咋回事啊?我明明改了对象,咋就没生效呢?”

我一看,原来是他没搞清楚值传递和引用传递的区别。于是,我就给他好好上了一课,让他明白了其中的奥秘。今天,我就把这些经验分享给大家,让你们也能少走弯路。

正文

🎯主要目标

1. 啥是值传递和引用传递?为啥Java里只有值传递?

2. 哪些情况容易让人误以为是引用传递?

3. 如何正确地在方法里修改对象?

4. 狗哥的实战经验总结,让你从此告别传递困惑!

🍪目标讲解

一. 啥是值传递和引用传递?

1. 你眼中的传递:简单直接!

在程序员的世界里,方法调用和参数传递是再常见不过的操作了。比如下面这段代码:

public class PassExample {
    public static void main(String[] args) {
        int num = 10;
        modifyNumber(num);
        System.out.println("num 的值是:" + num);
    }

    public static void modifyNumber(int number) {
        number = 20;
    }
}

这段代码看起来很简单,就是定义了一个变量num,然后把它作为参数传递给modifyNumber方法,在方法里把参数的值改成了20。但是,当我们运行这段代码时,会发现输出的结果是num 的值是:10,而不是20。这是为啥呢?这就涉及到值传递和引用传递的概念了。

2. 值传递闪亮登场:我只复制,不改变原数据!

值传递,简单来说,就是在方法调用时,把实际参数的值复制一份传递给形式参数。也就是说,方法里操作的是复制后的副本,而不是原数据。就像你有一份文件,你复印了一份给别人,别人在复印的文件上修改,不会影响你原来的文件。

在上面的例子中,num的值是10,当我们把num作为参数传递给modifyNumber方法时,实际上是把10这个值复制了一份给number。在modifyNumber方法里,我们把number的值改成了20,但这只是修改了副本的值,原数据num的值并没有改变。

3. 引用传递:我能直接改变原数据!

引用传递,是指在方法调用时,把实际参数的引用(也就是内存地址)传递给形式参数。这样,方法里操作的就是原数据,而不是副本。就像你把文件的存放地址告诉别人,别人可以直接去那个地址修改文件,这样就会影响你原来的文件。

不过,需要注意的是,Java里只有值传递,没有引用传递。很多人会误以为Java里有引用传递,是因为在处理对象时,会出现一些看似是引用传递的情况。

4. Java里的对象传递:其实还是值传递!

在Java里,对象变量存储的是对象的引用(内存地址)。当我们把对象作为参数传递给方法时,实际上是把对象的引用复制了一份传递给方法。也就是说,方法里操作的是复制后的引用副本,而不是原引用。

看下面这个例子:

class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }
}

public class ObjectPassExample {
    public static void main(String[] args) {
        Person person = new Person("狗哥");
        modifyPerson(person);
        System.out.println("person 的名字是:" + person.name);
    }

    public static void modifyPerson(Person p) {
        p.name = "张三";
    }
}

在这个例子中,我们创建了一个Person对象person,并把它作为参数传递给modifyPerson方法。在modifyPerson方法里,我们修改了pname属性。运行这段代码,会发现输出的结果是person 的名字是:张三,好像对象被修改了,就像引用传递一样。

但实际上,这还是值传递。我们传递的是person对象的引用副本,虽然副本和原引用指向同一个对象,但它们是两个不同的变量。在方法里,我们通过副本引用修改了对象的属性,所以对象本身被修改了。但如果我们在方法里让副本引用指向另一个对象,原引用是不会受到影响的。

看下面这个例子:

class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }
}

public class ObjectPassExample2 {
    public static void main(String[] args) {
        Person person = new Person("狗哥");
        changePerson(person);
        System.out.println("person 的名字是:" + person.name);
    }

    public static void changePerson(Person p) {
        p = new Person("张三");
    }
}

在这个例子中,我们在changePerson方法里让p指向了一个新的Person对象。运行这段代码,会发现输出的结果是person 的名字是:狗哥,原对象并没有被改变。这就说明,我们传递的是引用副本,而不是原引用。


二. 哪些情况容易让人误以为是引用传递?

1. 修改对象属性:看似引用传递,实则值传递!

就像上面的Person对象例子,我们在方法里修改了对象的属性,看起来好像是引用传递。但实际上,我们只是通过引用副本修改了对象本身,而不是修改了引用。

2. 数组传递:同样是值传递!

数组在Java里也是对象,当我们把数组作为参数传递给方法时,也是传递的数组引用副本。看下面这个例子:

public class ArrayPassExample {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        modifyArray(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }

    public static void modifyArray(int[] array) {
        array[0] = 10;
    }
}

在这个例子中,我们在modifyArray方法里修改了数组的第一个元素。运行这段代码,会发现输出的结果是10 2 3,数组被修改了。但这还是值传递,我们传递的是数组引用副本,通过副本引用修改了数组本身。


三. 如何正确地在方法里修改对象?

1. 修改对象属性:直接修改!

如果我们想在方法里修改对象的属性,直接通过引用副本修改就可以了。就像上面的Person对象和数组例子一样。

2. 返回修改后的对象:重新赋值!

如果我们想让方法返回一个修改后的对象,并且让原引用指向这个新对象,我们可以在方法里返回修改后的对象,然后在调用方法的地方重新赋值。看下面这个例子:

class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }
}

public class ReturnModifiedObjectExample {
    public static void main(String[] args) {
        Person person = new Person("狗哥");
        person = changePerson(person);
        System.out.println("person 的名字是:" + person.name);
    }

    public static Person changePerson(Person p) {
        p = new Person("张三");
        return p;
    }
}

在这个例子中,我们在changePerson方法里创建了一个新的Person对象,并返回了这个对象。在main方法里,我们把返回的对象重新赋值给person,这样person就指向了新的对象。


四. 狗哥的实战经验总结!

  1. 牢记Java只有值传递: 无论传递的是基本数据类型还是对象,都是值传递。传递的是值的副本或者引用的副本。

  2. 区分修改对象属性和修改引用: 修改对象属性是通过引用副本修改对象本身,而修改引用是让引用指向另一个对象。

  3. 正确处理对象修改: 如果想修改对象属性,直接通过引用副本修改;如果想让原引用指向新对象,通过返回值重新赋值。

  4. 理解原理,避免混淆: 搞清楚值传递和引用传递的区别,以及Java里只有值传递的原因,就能避免很多传递困惑。

🍈猜你想问

如何与博主联系进行探讨

关注公众号【JavaDog程序狗】

公众号回复【入群】或者【加入】,便可成为【程序员学习交流摸鱼群】的一员,问题随便问,牛逼随便吹,目前群内已有超过380+个小伙伴啦!!!

2. 踩踩博主博客

javadog.net

里面有博主的私密联系方式呦 !,大家可以在里面留言,随意发挥,有问必答😘

🍯猜你喜欢

文章推荐

【实操】Spring Cloud Alibaba AI,阿里AI这不得玩一下(含前后端源码)

【规范】看看人家Git提交描述,那叫一个规矩

【项目实战】SpringBoot+uniapp+uview2打造H5+小程序+APP入门学习的聊天小项目

【项目实战】SpringBoot+uniapp+uview2打造一个企业黑红名单吐槽小程序

【模块分层】还不会SpringBoot项目模块分层?来这手把手教你!


评论