Java调用函数传递参数到底是值传递还是引用传递

  今天翻看微信上有关Java技术的公众号时,看到了一篇关于Java中值传递的问题,文章讨论了在Java中调用函数进行传参的时候到底是值传递还是引用传递这个面试时会问到的问题。之前也接触过类似的问题,但只是知道是值传递,具体到为什么,一直不是太清楚。今天看了一下,算是明白了,写个博客记录一下。

  首先先声明一下,在Java中函数传参是值传递,不是引用传递。要弄清楚这个问题之前要先弄清楚什么是值传递,什么是引用传递。

  值传递(pass by value):是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

  引用传递(pass by reference):是指在调用函数时将实际参数的地址直接传递到函数中,这样在函数中如果对参数进行修改,将影响实际参数。

  请注意我红色标记的字,很关键。相信很多人对于是值传递还是引用传递都会有这样一种认识:在传递基本数据类型的时,是值传递,在传递引用数据类型时是引用传递。原因不过就是像下面这样的代码所表现出来的。

package com.wuqi.p1;

public class ValuePassTest {

    public static void main(String[] args) {
        int a = 1;
        //传递基本数据类型,因为是将a的值传递给param,所以即便在pass函数中改变了从
        //参数的值,a的值还是不会变。所以我们认为在传递基本数据类型的时候是值传递
        pass(a);
        System.out.println("a= " + a);
    }

    private static void pass(int param) {
        param = 2;
        System.out.println("param= " + param);
    }

}

package com.wuqi.p1;

import com.wuqi.p2.User;

public class PassTest2 {

    public static void main(String[] args) {
        User user = new User();
        user.setName("wutianqi");

        //传递对象,因为是将指向User的引用user传递给了param,
        //在函数中param.setName会反应到真实的对象中去。因此我们
        //认为在这种情况下是引用传递
        pass(user);
        System.out.println("my name is " + user.getName());
    }

    private static void pass(User param) {
        param.setName("wuqi");
        System.out.println("my name is " + param.getName());
    }

}

包括我自己以前也是这么认为的。但是我们都没有注意到这样一个问题。请看代码

package com.wuqi.p1;

public class PassTest3 {
    public static void main(String[] args) {
        String name = "wutianqi";

        //这里传递字符串参数,按照我们以前的观点这里应该传递的是将指向字符串的name引用
        //传递给param,那么在pass函数中修改参数的值会直接影响到name引用指向的字符串
        //的值,那么输出的结果依此应该是 my name is wuqi  my name is wuqi
        pass(name);
        System.out.println("my name is " + name);
    }

    private static void pass(String param) {
        param = "wuqi";
        System.out.println("my name is " + param);

    }
}

这段代码按照我们对象是引用传递的思想,输出的结果就应该是代码中所说的那样。但是真实输出的结果确实下面这样

哎呦!什么情况!颠覆了你的认知?当初看到这段代码我也是大吃一惊!这说明之前的认识是错的!

别慌!让我们在看一下值传递和引用传递的概念吧。这里我标红的字体起作用了。引用传递是直接传递引用,那么在函数中对参数进行修改将会影响到实际参数。按照这个理论,那么毫无疑问,通过上面的例子,引用传递对于Java函数参数传递来说是错误的。在看看值传的概念,值传递是将实际参数复制一份,对参数的改变不会影响到实际参数。注意复制这两个字!!!在上面的例子中,如果我们认为是复制了name引用,也就是复制了name引用的值,然后传递给param。param="wuqi",其实相当于param=new String("wuqi"),这时param指向了一个新的对象。而实际参数name还是指向原来的对象。这样的话输出的结果和正确的就对上了。这样也就证明了在Java中是值传递而不是引用传递。

对于对象来说传递的是引用的一个副本给参数,这一点要铭记!

原文地址:https://www.cnblogs.com/wutianqi/p/8723582.html

时间: 2024-10-12 15:29:46

Java调用函数传递参数到底是值传递还是引用传递的相关文章

javascript学习笔记(二):定义函数、调用函数、参数、返回值、局部和全局变量

定义函数.调用函数.参数.返回值 关键字function定义函数,格式如下: function 函数名(){ 函数体 } 调用函数.参数.返回值的规则和c语言规则类似. 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta chaset="UTF-8"> 5 <title></title> 6 </head> 7 <body

JS中函数的本质,定义、调用,以及函数的参数和返回值

要用面向对象的方式去编程,而不要用面向过程的方式去编程 对象是各种类型的数据的集合,可以是数字.字符串.数组.函数.对象…… 对象中的内容以键值对方式进行存储 对象要赋值给一个变量 var cat={ "name":"喵1", "age":4, "family":["喵爸","喵妈"], "speak":function(){ console.log("喵喵

c&amp;c++函数的参数和返回值的传递终结版

c++函数的参数和返回值的传递方式有三种:值传递.指针传递和引用传递. 在这之前先看几个例子: 一, int a=10; int b=a; b+=10; 此时b是a的一个拷贝,改变b的值,a并不会受到影响,所以此时 a=10; b=20;二, int a=10; int &b=a; b+=10; 此时b是a的引用,对于b的任何操作都相当于对a进项操作,对于b的任何操作也都相当于对a的操作,a就是b,b就是a,所以此时a,b的值都为20.三, int a=10; int *b=&a; *b+

Java技术_Java千百问(0039)_引用传递和值传递有什么区别

点击进入_更多_Java千百问 1.什么是值传递 值传递,是将内存空间中某个存储单元中存放的值,传送给另一个存储单元.(java中的存储单元并不是物理内存的地址,但具有相关性) 例如: //定义了一个改变参数值的函数 public static void changeValue(int x) { ??x = x *2; } public class TestMain{ //调用该函数 int num = 5; System.out.println(num); changeValue(num);

C++笔记(3):函数的参数和返回值

刚学C++那会,做课程设计的时候总是会去网上很找别人写好的程序来参考,那时候看到函数参数列表里各种复杂的类型和奇怪的写法就头大,后来总算是慢慢搞清楚了,在此对函数各种类型的形参以及函数的返回值进行一下总结. 1.普通形参 传递普通形参也就是值传递,传递的是实际参数的一个副本,当函数被调用时,形参复制实参,也就是说此时形参和实参的值是一样的,但形参在内存中拥有自己的地址.当函数结束时形参的生命周期终止,函数内部的操作不会影响到实参的值.经典的值交换函数代码如下: void swap1(int a,

Python——变量的引用和函数的参数和返回值的传递方式

变量的引用 在python中,所有的变量都是指向地址,变量本身不保存数据,而是保存数据在内存中的地址.我们用下面的程序来理解: 1 a = 10 2 print(id(a)) 3 a = 11 4 print(id(a)) (利用id( )方法查看数据的地址) 输出结果为: 可以发现:修改变量的值,变量保存的地址随之改变. python中: 变量和数据是分开存储的 变量 中保存着数据在内存中的地址 我们把变量中记录数据的地址的行为,叫做 引用. 通俗的来说,在 Python 中,变量的名字类似于

JavaScript-4.3函数的参数和返回值,参数数目不确定的函数调用---ShinePans

<html> <head> <meta http-equiv="content-type" vontent="text/html;charset=GB2312"/> <title> 4.3 参数数目不明确的函数调用 </title> <!--脚本部分--> <script type="text/javascript"> function a(){ var str=

java 一个函数EnumMap返回多个值

java 一个函数如何返回多个值 在开发过程中,经常会有这种情况,就是一个函数需要返回多个值,这是一个问题!! 网上这个问题的解决方法: 1.使用map返回值:这个方法问题是,你并不知道如何返回值的key是什么,只能通过doc或者通过源代码来查看. 2.传入一个引用进去,修改引用的属性值.问题:不实用. 3.通过泛型构造一个类似python的tuple类,或者构造一个JavaBean,其问题都是“一次性”,觉的不优雅. 个人解决方案: 使用EnumMap作为返回值类型,自己定义一个enum,将可

创建数组,用函数分别实现初始化、清空和逆置。自己设计函数的参数,返回值

创建一个数组, 实现函数init()初始化数组. 实现empty()清空数组. 实现reverse()函数完成数组元素的逆置. 要求:自己设计函数的参数,返回值.*/ #include<stdio.h> #include<cstdlib> void init(int* arr, int length)//没有为arr开辟空间  可以不初始化. { int i = 0; for (i = 0; i<length; i++) { arr[i] = i;// scanf_s(&qu