Java中的参数传递是值传递还是引用传递?

结论:在Java中,参数传递都是值传递,没有引用传递

形参和实参

参数一般可以分为形式参数和实际参数,先看一下各自的定义。

形参:在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。

实参:在主函数中调用另一个函数时,函数中传递的就是实际参数(括号中的参数)。

示例:

public class Test {
    public static void main(String[] args) {
        Test pt = new Test();
        //“张三”为实际参数
        pt.sout("张三");
    }

    public void sout(String name) {
        //name为形式参数
        System.out.print(name);
    }
}

 

值传递和引用传递

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

引用传递:是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

 

(1)基本类型参数测试:

public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        int i = 100;
        System.out.println("inc方法调用前,i的值为=" + i);
        test.inc(i);
        System.out.println("inc方法调用后,i的值为=" + i);
    }

    private void inc(int i) {
       i ++;
       System.out.println("inc方法中,i的值为=" + i);
    }
}

结果:
inc方法调用前,i的值为=100
inc方法中,i的值为=101
inc方法调用后,i的值为=100

可以看出,main方法里的变量i,并不是inc方法里的i,inc方法内部对i的值的修改并没有改变实际参数i的值,改变的只是inc方法中i的值,因为inc方法中的i只是main方法中变量i的复制品

因此容易得出结论:Java中,一个方法不可能修改一个基本数据类型的参数 ,所以是值传递。

 

(2)引用类型参数测试:

public class Test {
    public static void main(String[] args) {
        Test test = new Test();

        User user = new User();
        user.setUsername("张三");
        user.setAge(20);

        System.out.println("updateUser方法调用前,user为" + user.toString());
        test.updateUser(user);
        System.out.println("updateUser方法调用后,user为" + user.toString());

    }

    private void updateUser(User updateUser) {
        updateUser.setUsername("李四");
        System.out.println("updateUser方法中,user为" + updateUser.toString());
    }
    
    static class User {
        private String username;
        private Integer age;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
}

执行结果:

updateUser方法调用前,user为User{username='张三', age=20}
updateUser方法中,user为User{username='李四', age=20}
updateUser方法调用后,user为User{username='李四', age=20}

Java中传递引用数据类型的时候也是值传递,为什么呢?

因为复制的是参数的引用(地址值),并不是引用指向的存在于堆内存中的实际对象,简图如下图所示:

 

main方法中的user是一个引用(也就是一个指针),它保存了User对象的地址值,当把user的值赋给updateUser()方法的user形参后,即让updateUser()方法的user形参也保存了这个地址值,即也会引用到堆内存中的User对象。

上面代码中,之所以产生引用传递的错觉,是因为参数保存的是实际对象的地址值,你改变的只是地址值指向的堆内存中的实际对象,并没有真正改变参数,参数的地址值没有变。

 

场景引入:

你有一把钥匙,当你的朋友想要去你家的时候,如果你直接把你的钥匙给他了,这就是引用传递。这种情况下,如果他对这把钥匙做了什么事情,比如他在钥匙上刻下了自己名字,那么这把钥匙还给你的时候,你自己的钥匙上也会多出他刻的名字。

你有一把钥匙,当你的朋友想要去你家的时候,你复刻了一把新钥匙给他,自己的还在自己手里,这就是值传递。这种情况下,他对这把钥匙做什么都不会影响你手里的这把钥匙。

但是,不管上面哪种情况,你的朋友拿着你给他的钥匙,进到你的家里,把你家的电视砸了。那你说你会不会受到影响?

 

什么是真正的改变参数?

public class Test {
    public static void main(String[] args) {
        Test test = new Test();

        User user = new User();
        user.setUsername("张三");
        user.setAge(20);

        System.out.println("updateUser方法调用前,user为" + user.toString());
        test.updateUser(user);
        System.out.println("updateUser方法调用后,user为" + user.toString());

    }

    private void updateUser(User user) {
        //改变了user参数,指向了一个新的地址
        user = new User();
        user.setUsername("李四");
        user.setAge(50);
        System.out.println("updateUser方法中,user为" + user.toString());
    }

    static class User {
        private String username;
        private Integer age;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
}

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值