java值传递及其引起的问题

关于java的值传递与引用传递的问题,我们先来看一下百度百科的定义:

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

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

根据定义来看,值传递与引用传递的区别就是,在函数中修改形参,是否会影响到实参。

接下来先看一个例子:

public static void main(String[] args) {
    String a = "before";
    System.out.println(a);
    change(a);
    System.out.println(a);
}
public static void change(String a) {
    a = "after";
}

运行的结果是:

before change: before
after change: before

 可以看出来,在change方法中修改形参并没有影响到实参。

我们再来看另一种例子:

public static void main(String[] args) {
    User user = new User();
    user.setId(0);
    System.out.println("before change: " + user.getId());
    changeUser(user);
    System.out.println("after change: " + user.getId());
}
public static void changeUser(User user) {
    user.setId(1);
}

 运行的结果是:

before change: 0
after change: 1

这样子看起来,在changUser方法中修改形参的值影响到了实参,这又是怎么回事呢?

我们先来分析下第一种情况:

如上图所示,我们在change方法中修改了形参所指向的地址,指向After,实参依然指向Before。

我们再来分析下第二种情况:

如上图所示,我们在change方法中修改了user中id的值,形参所指向的地址没有变化,修改的是这个地址中的内容。所以实参指向的user的id发生了变化,所以Java是值传递,形参的修改并不会影响实参。

我们再来看看Java值传递会引起的问题,举个例子:

public static void main(String[] args) {
    List<User>  userList = new ArrayList<>();
    User user = new User();
    for(int i = 0; i < 10; i ++) {
        user.setId(i);
        userList.add(user);
    }
    System.out.println();
    for(User u: userList) {
        System.out.print(u.getId() + ",");
    }
}

运行的结果是:

9,9,9,9,9,9,9,9,9,9,

为什么输出的都是9呢?我们命名是从0到9设置user的id,应该输出0到9才对。我们用一个图来说明。

userList中存的是user的地址,其实我们添加进去的都指向同一个地址,所以输出上边的结果。

所以我们在实际运用中要注意,add之前要先重新new一下,这样add进去的就是新的地址。不仅List,Map等也是一样的道理,要留意Java值传递引起的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值