前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么说Java中只有值传递?

为什么说Java中只有值传递?

原创
作者头像
诺浅
修改2020-08-19 14:42:15
5350
修改2020-08-19 14:42:15
举报
文章被收录于专栏:工具使用

重新定义什么是值传递和引用传递

相信我,当你正在看这篇文章的时,说明你对值传递和引用传递的理解大概率是错误的。如果你理解的是正确的,你应该也不会来看这篇文章。

在这里插入图片描述
在这里插入图片描述

正确的定义

  • 值传递:参数传递时,是拷贝实参的副本,然后传递给形参。
  • 引用传递:参数传递时,直接把对象的引用传给了形参。

你在问什么是实参,什么是形参对不对?对不对

形参与实参

  • 形参是指在定义函数时使用的参数,目的是用于接收调用该函数时传入的参数。简单理解,就是所有函数(即方法)的参数都是形参。
  • 实参,是指调用函数时,传递给函数的参数。
代码语言:txt
复制
public static void main(String[] args) {
    int num = 3;
    printVal(num); //这里num是实参
}

private static void printVal(int num) {
    num = 5; //这里num就是形参
}

Java中调用方法传递一个参数的过程是怎样的?

当传递的参数是基本数据类型时

代码语言:txt
复制
public class TestNum {
    public static void main(String[] args) {
        int num = 3;
        System.out.println("修改前的num值:"+num);
        changeValue(num);
        System.out.println("修改后的num值:"+num);
    }

    private static void changeValue(int num) {
        num = 5;
        System.out.println("形参num值:"+num);
    }
}

修改前的num值:3 形参num值:5

修改后的num值:3

你是不是觉得上诉例子是把num当成了实参传给了changeValue方法对不对?对不对?但你错了

真正的底层其实是把num拷贝了一个副本,然后把这个副本传给了changeValue

在这里插入图片描述
在这里插入图片描述

图中num是实参,然后创建了一个副本temp,把它传递个形参value,修改value值对实参num没有任何影响。

当传递的参数是引用类型时

代码语言:txt
复制
public class User {
    private int age;
    private String name;
    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public User(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
public class TestUser {
    public static void main(String[] args) {
        User user = new User(18, "zhangsan");
        System.out.println("修改对象前:"+user);
        changeUser(user);
        System.out.println("修改对象后:"+user);
    }

    private static void changeUser(User user) {
        user.setAge(20);
        user.setName("lisi");
    }
}

修改对象前:User{age=18, name='zhangsan'} 修改对象后:User{age=20, name='lisi'}

你是不是想说,这次总是引用传递了吧,毕竟对象都被改变了,对不对,对不对?但其实你又错了。文章一开始就说了,我们理解的引用传递其实并不是引用传递真正的定义。对象是被改变了,但这并不能代表引用传递,引用传递与我们传递的参数是不是原始变量有关,那么上诉例子的实际过程是下面这样的

在这里插入图片描述
在这里插入图片描述

user是对象的引用,为实参,然后创建一个副本temp,把它传递给形参user1。但是,他们实际操作的都是堆内存中的同一个User对象。因此,对象内容的修改也会体现到实参user上。那么也就是说,还是传递的是副本,并不是原始的对象的本身,所以还是值传递。

总结

与很多人一样,我也以为传递的是对象就是引用传递。但其实这一点是错误的。真正的引用传递并不是这样定义的,Java传递参数也并不像我们表面看到的那样简单。

参考:https://segmentfault.com/a/1190000021529503

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 重新定义什么是值传递和引用传递
  • Java中调用方法传递一个参数的过程是怎样的?
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档