ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

值传递和引用传递

2022-04-05 11:01:15  阅读:151  来源: 互联网

标签:name 形参 传递 Person 引用 实参 public


首先 不管下面说什么, 公论:Java 只有值传递,没有引用传递

官方的话:

值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

参数传递 可以理解当我们要调用一个方法时,我们会把指定的数值,传递给方法中的参数,这样方法中的参数就拥有了这个指定的值,可以使用该值,在方法中运算了。这种传递方式,我们称为参数传递。

我们来总结一下,值传递和引用传递之前的区别的重点是什么。

值传递 引用传递
根本区别 会创建副本(copy) 不创建副本
所以 函数中无法改变原始值 函数可以改变原始值

官方的话也是非常的官方了!

简单点说:

在此之前,我们先搞懂两个概念

实参和形参

public static void main(String[] args) {
    int a = 8; // 实参
    f(a);
}

public static void f(int a){
    System.out.println(a);  // 形参
}

实参,就是我们要传递给方法的,在方法外面

形参,就是我们方法签名上定义的参数,在方法里面

那么,值传递和引用传递的区别是什么呢?

简单粗暴来说:

对形参的修改不会影响到实参,那就是值传递,

对形参的修改能够影响到实参,那就是引用传递

例1:

  (回到图示)
    public static void main(String[] args) {
        int a = 8; // 实参
        f(a);
        System.out.println("实参:" + a);
    }

    public static void f(int a){
        a = 16;
        System.out.println("形参:" + a);
    }

/*打印结果:
    形参:16
    实参:8
    */

​ 如果我们将基本数据类型的值,传递到方法中,然后在方法内修改形参的值,最后

打印实参和形参。

​ OK!来看打印结果,可以发现,形参修改了,并没有影响到实参。这很符合值传递。

​ 我们再来看非基本数据类型,也就是对象,

public class Person {

    public String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}

当我们将一个对象变量,传递到方法中,然后在方法内修改对象的属性,再打印实参和形参

例2:

  (回到图示)
public static void main(String[] args) {
    Person p = new Person("张三");
    f(p);
    System.out.println("实参:" + p);
}

public static void f(Person p) {
    p.name = "李四";
    System.out.println("形参:" + p);
}

/*
* 打印结果:
* 形参:Person{name='李四'}
  实参:Person{name='李四'}
* */

会发现实参和形参的都被修改了,这样看起来 java 好像也支持引用传递呀!

别急,你别着急!

我们再来看看这个例子,

例3:

  (回到图示)
public static void main(String[] args) {
    Person p = new Person("张三");
    f(p);
    System.out.println("实参:" + p);
}

public static void f(Person p) {
    p =new Person("李四") ;
    System.out.println("形参:" + p);
}


/*
*打印结果:
* 形参:Person{name='李四'}
* 实参:Person{name='张三'}
* 
* */

如果我们创建一个新对象,并赋值给形参,此时再打印

会发现实参和形参已经互不影响了,

要理解这些现象,我们需要搞懂。。。

在 JVM 中,划分了好几块内存区域,其中就有一个栈空间,和一个堆空间

我们创建所有的对象都存放在堆中,而基本数据类型局部变量是存放在栈中的

(来看刚才的例1)

当传递基本数据类型时,是将数据创建了一个副本,传递到方法中,那自然形参修改也不会影响到实参,符合值传递。

当操作对象时就要注意了,对象是存放在堆中的。

我们拿到的只是对象的引用,通过对象的引用,就可以操作对象。

这也就是说为什么说,java 数据类型,分为两种,一种是基本数据类型,一种是引用数据类型。

我们来回顾 (第二个例子(点击))

当对象引用传递给方法时,其实是创建了一个引用副本,实参和形参都指向了同一个对象,所以通过形参引用操作对象时,显得实参好像改变了。

但实参本身是没有改变的,因为实参就是原先的那个引用嘛,就是一个遥控器,电视机内容改变了,遥控器本身又没有改变。

(例3)

​ 所以我们将形参重新赋值的时候,实参是不会受到任何影响的。此时形参和实参指向不同的对象。

总结:

​    java 完全就是值传递的,如果是基本数据类型,那就复制一份值传递给形参,如果是引用数据类型,那就将引用复制一份传递给形参,形参始终拿到的都是一份副本,无论如何,都无法通过形参改变实参,毕竟形参只是操作的副本而已。

内容参考 RudeCrab

标签:name,形参,传递,Person,引用,实参,public
来源: https://www.cnblogs.com/zou-ma/p/16101676.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有