值传递和引用传递

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

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

举例
/**
 * 证明java值传递demo
 *
 * @author miao
 */publicclassPassValueDemo {

    publicstaticvoidmain(String[] args) {

        inta=1;
        Stringstr="1";
        Useruser=newUser("阿花", 6);

        System.out.println("调用方法前a为:" + a);
        System.out.println("调用方法前str为:" + str);
        System.out.println("调用方法前user为:" + user);

        System.out.println("------------------------------------------");
        convert(a, str, user);
        System.out.println("------------------------------------------");

        System.out.println("调用方法后a为:" + a);
        System.out.println("调用方法后str为:" + str);
        System.out.println("调用方法后user为:" + user);
    }

    privatestaticvoidconvert(int a, String str, User user) {
        a = 2;
        str = "2";
        user.setAge(9);
        user.setUsername("大壮");

        System.out.println("调用方法中a为:" + a);
        System.out.println("调用方法中str为:" + str);
        System.out.println("调用方法中user为:" + user);
    }

}

/**
 * @author miao
 */classUser {

    public String username;

    publicint age;

    publicUser(String username, int age) {
        this.username = username;
        this.age = age;
    }

    public String getUsername() {
        return username;
    }

    publicvoidsetUsername(String username) {
        this.username = username;
    }

    publicintgetAge() {
        return age;
    }

    publicvoidsetAge(int age) {
        this.age = age;
    }

    @Overridepublic String toString() {
        return"User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}
复制代码
程序的执行结果:
调用方法前a为:1
调用方法前str为:1
调用方法前user为:User{username='阿花', age=6}
------------------------------------------
调用方法中a为:2
调用方法中str为:2
调用方法中user为:User{username='大壮', age=9}
------------------------------------------
调用方法后a为:1
调用方法后str为:1
调用方法后user为:User{username='大壮', age=9}

我们可以看到,身为基本类型的int和被final修饰的String并没有改变,但是引用类型User改变了,所以,网上就有人得出了结论:java针对基本类型是值传递,对于引用类型是引用传递。但是!!!!这是错误的结论,不相信的话:

在convert()方法中str = "2";下面增加一行user = new User("小美", 18),让我们看看这样的结果是什么?
程序的执行结果:
调用方法前a为:1
调用方法前str为:1
调用方法前user为:User{username='阿花', age=6}
------------------------------------------
调用方法中a为:2
调用方法中str为:2
调用方法中user为:User{username='大壮', age=9}
------------------------------------------
调用方法后a为:1
调用方法后str为:1
调用方法后user为:User{username='阿花', age=6}
从上述结果可以看出,当我们在 convert 方法中添加 user = new User("小美", 18)之后,“引用传递”就突然变值传递了?为什么?

这是因为,在 Java 语言中本质上只有值传递,也就说 Java 的传参只会传递它的副本,并不会传递参数本身。

即传入convert()时的user为 User user 的副本,指向同一个new User("阿花", 6)的堆地址,

当执行user = new User("小美", 18)时,指向的堆内存改变了,所以再进行任何操作都跟之前的堆地址没关系了,即证实了,传递的是一个副本。

虽然是个副本,但这个副本引用也是会指向堆内存地址的,副本引用和源数据引用指向同一个内存地址

未执行user = new User("小美", 18)之前

在方法函数中执行user = new User("小美", 18)之后

副本引用和源数据引用指向的是堆中不同的内存地址;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值