java中值传递和引用传递

2023-10-26

值传递

package com.github.hcsp;

public class Main {
  public static void main(String[] args) {
    int i = 0;
    addOne(i);
    System.out.println(i);
  }

  static void addOne(int i) {
    i++;
  }
}


//输出结果为 0

因为 addOne 方法中传递的 i 只是 main 方法中的 i 的值的拷贝,所以不会对其产生任何影响。在执行完 addOne 方法以后,该方法空间会被销毁。

引用传递

package com.github.hcsp;

public class Main {
  public static void main(String[] args) {
    Cat cat = new Cat();
    cat.name = "haha";

    renameCat(cat);

    System.out.println(cat.name);
  }

  static void renameCat(Cat cat){
    cat.name = "mimi";
  }
}

//输出结果为mimi

为什么该程序就会改变 cat 的名字呢?因为方法中传递的是 Cat 变量引用 (地址) 的拷贝,所以,在 rename 方法中的 cat 指向的也是内存中同一只 “猫”。

Java 中有两种数据类型:

基本数据类型: int char byte boolean float double short long

引用数据类型 类 接口 数组

1 、从概念方面来说
1.1, 基本数据类型 : 变量名指向具体的数值
1.2, 引用数据类型 : 变量名不是指向具体的数值 , 而是指向存数据的内存地址 ,. 也及时 hash 值
2 、从内存的构建方面来说 ( 内存中 , 有堆内存和栈内存两者 )
2.1, 基本数据类型 : 被创建时 , 在栈内存中会被划分出一定的内存 , 并将数值存储在该内存中 .
2.2, 引用数据类型 : 被创建时 , 首先会在栈内存中分配一块空间 , 然后在堆内存中也会分配一块具体的空间用来存储数据的具体信息 , 即 hash 值 , 然后由栈中引用指向堆中的对象地址 .基本数据类型中会存在两个相同的 1 ,而引用型类型就不会存在相同的数据。
假如 “hello” 的引用地址是 xxxxx1 ,声明 str 变量并其赋值 “hello” 实际上就是让 str 变量引用了 “hello” 的内
存地址,这个内存地址就存储在堆内存中,是不会改变的,当再次声明变量 str1 也是赋值为 “hello” 时,
此时就会在堆内存中查询是否有 “hello” 这个地址,如果堆内存中已经存在这个地址了,就不会再次创建
了,而是让 str1 变量也指向 xxxxx1 这个地址,如果没有的话,就会重新创建一个地址给 str1 变量。

请谈一下值传递与引用传递?Java 中只有值传递么?

我们通过上面的程序简单了解了什么叫 “值”,什么叫 “引用”,接下来我们重点介绍一下值传递与引用传递。

请不要忽视这个问题,它也许没有你想的那么简单。绝大部分初学者很难搞懂究竟什么是值传递,什么是引用传递。

很多博客中,作者不仅没有解释清楚 “值传递” 与 “引用传递”,还混淆了很多错误的引导。

所以,在回答这个问题之前,我们先进行一次排雷检查,看一看你是否对值传递与引用传递有着错误的理解:

【观点 1】Java 中既有值传递也有引用传递
【观点 2】Java 中只有值传递,因为引用的本质就是指向堆区的一个地址,也是一个值。
如果你的观点符合上述两种观点的其中一种,那么你多半没有理解值传递和引用传递的概念。话不多说,接下来我来详细说明究竟什么是值传递,什么是引用传递,以及 Java 中为什么只有值传递。

值传递(Pass by value)与引用传递(Pass by reference)属于函数调用时,参数的求值策略(Evaluation Strategy)。求值策略的关注点在于,求值的时间以及传值方式:

求值策略 求值时间 传值方式
Pass by value 函数调用前 原值的副本
Pass by reference 函数调用前 原值(原始对象)
所以,区别值传递与引用传递的实质并不是传递的类型是值还是引用,而是传值方式,传递的是原值还是原值的副本。

如果传递的是原值(原对象),就是引用传递;如果传递的是一个副本(拷贝),就是值传递。再次强调一遍,值传递和引用传递的区别在于传值方式,和你传递的类型是值还是引用没有一毛钱关系!

Java 语言之所以只有值传递,是因为:传递的类型无论是值类型还是引用类型,Java 都会在调用栈上创建一个副本,不同的是,对于值类型而言,这个副本就是整个原始值的复制;而对于引用类型而言,由于引用类型的实例存储在堆中,在栈上只有它的一个引用,指向堆的实例,其副本也只是这个引用的复制,而不是整个原始对象的复制。

我们通过两个程序来理解下:

程序一:

public class Test {
    public static void setNum1(int num){
        num = 1;
    }
    public static void main(String[] args) {
        int a = 2;
        setNum1(a);
        System.out.println(a);
    }
}

程序二

public class Test2 {
    public static void setArr1(int[] arr){
        Arrays.fill(arr,1);
    }
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        setArr1(arr);
        System.out.println(Arrays.toString(arr));
    }
}

程序一输出的结果为:2
程序二输出的结果为:[1,1,1,1,1]

程序一中,Java 会将原值复制一份放在栈区,并将这个拷贝传递到方法参数中,方法里面仅仅是对这个拷贝进行了修改,并没有影响到原值,所以程序一的输出结果为 2。

程序二中,Java 会将引用的地址复制一份放在栈区,复制的拷贝和原始引用都指向堆区的同一个对象。方法通过拷贝地址找到堆区的实例,对堆区的实例进行修改,而此时,原始引用仍然指向着堆区的实例,程序二的输出结果为:[1,1,1,1,1]

所以,在 Java 中,对于方法的参数传递,无论是原生数据类型,还是引用数据类型,本质上是一样的。

如果是传值,那就将值复制一份,如果是传引用(地址),就将引用(地址)复制一份。因为传入方法中的都是原始值的复制,所以说,Java 中只有 “值传递”。

参考链接

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中值传递和引用传递 的相关文章

随机推荐

  • 电脑开机后卡死,桌面图标点了没反应怎么办

    今天接到客户的电话 说一台台式办公PC出现故障 具体故障现象如下 电脑可以正常开机 开机后点击桌面上的所有图标都没反应 开始菜单可以点开 点开后里面的内容也无法点击打开 右键点击桌面下方启动栏可以点出来选项卡 但是点击选项卡里的内容无法打开
  • 写代码遇到Qt相关问题

    目录 qt clicked 函数 传递数据 QT读取文件个数 QT读txt数据并求出行数和列数 qt读写json 我的json文件 读写函数 换行和不换行的区别就是参数Indented和Compact的区别 把json写到文件中 QT信号槽
  • 低通滤波器算法实现_控制算法之超前-滞后补偿器(Lead_Lag Compensator)

    Lead Lag控制器主要从频域的角度来对被控系统进行校正 改善系统的频域特性 如相角裕度 幅值裕度以及灵敏度等 从而改善系统的稳定性及控制精度 是一种基于频率响应的校正方法 时域的卷积 频域的乘积 这句话很重要 深入理解 一 Lead L
  • flutter 防止widget rebuild(亲测有效2020篇)

    相比这个问题很多开发着都已经遇到了 头疼了很久了吧 我也是 网上搜到各种方法 试了还是不行 下面我举一下场景 跳转场景 页面A gt 页面B gt 页面C gt 页面D 从上面简单都例子 我很悲催的告诉大家不管我从哪个页面跳哪个页面 从B
  • Awk学习笔记

    Awk学习笔记 整理 Jims of 肥肥世家
  • windows下安装openssl的两种方式

    windows下按装openssl 第一种 第二种 因为工作需要第一次接触openssl 中间踩得坑实在是太多了 最后也算放弃了那种安装方式原则了一个比较简单的 第一种 第一种就是网上平常的说的方法 先下载 ActivePerl 5 24
  • 图文使用freetype渲染字体+字体颜色+字体大小

    freetype的介绍各种博客都有 可以搜索看看 freetype2 8的源码及编译出的库及头文件链接 https download csdn net download weixin 40550094 12117925 我这边就直接写dem
  • sql语句case when常用查询总结

    一 case when 语句语法逻辑 case when 是mySQL里面的控制流语句 和if then 的分支判断逻辑很相似 case when语句有两种 1 简单case when 2 case搜索函数法 简单case when只能处理
  • 大数据组件_Kafka学习

    Kafka学习 基本概念 1 Broker 每一台kafka机器节点就是一个broker 2 Producer 消息生产者 往kafka的topic写数据 3 Consumer 消息消费者 从kafka的topic读取数据 4 Topic
  • java生成大小写字母加数字的随机数

    小小的验证码的随机数生成 以前自己一直没有思考过 仔细想想其实实现起来并没有多难 只是自己没有想过这些东西的实现具体应该怎么做比较好 在自己思考后 参考了网上其他作者的一些代码 下面是具体的实现代码 public class Validat
  • LightGBM 原理、代码最全解读!

    来源 Microstrong 本文主要内容概览 1 LightGBM简介 GBDT Gradient Boosting Decision Tree 是机器学习中一个长盛不衰的模型 其主要思想是利用弱分类器 决策树 迭代训练以得到最优模型 该
  • 微信小程序如何访问本地的服务器,springboot2为例

    1 我们需要改一个配置就可以了 以springboot2的项目为例子 2
  • m.777lu.co/wap.php,MaliStore/app.wxss at master · kingpro/MaliStore · GitHub

    src url data font truetype charset utf 8 base64 AAEAAAALAIAAAwAwR1NVQrD s 0AAAE4AAAAQk9TLzJXBku4AAABfAAAAFZjbWFwX864igAA
  • 请问投稿中要求上传的author_SCI投稿过程中主要有哪些状态,持续时间大概多久?...

    原标题 SCI投稿过程中主要有哪些状态 持续时间大概多久 不同出版社旗下SCI杂志的投稿方式 过程以及状态有所区别 但是基本形式大致相同 我们掌握一种杂志的投稿及投稿状态 基本可以以一推百 不同杂志的审稿周期差异比较大 从几天到数月不等 甚
  • ElasticSearch字符串数组类型的精确查询与模糊查询(自定义分词后进行精确与模糊查询)

    一条数据中 有这样的一个字段Keyword Computational devices S models 现需要实现通过分号分词后来查询数据 查询规则如下 1 检索Computational 不区分大小写 时命中结果 2 检索Computa
  • linux中使用crontab设置定时任务

    1 crontab简介 crontab命令常见于 Unix和类Unix 的操作系统之中 用于设置周期性被执行的指令 该命令从标准输入设备读取指令 并将其存放于 crontab 文件中 以供之后读取和执行 crontab储存的指令被守护进程激
  • docker 安装 elasticsearch和kibana(亲测可行)

    1 版本可自己更换 docker pull elasticsearch 6 6 1 2 创建本地挂在目录 mkdir p usr share elasticsearch share config mkdir p usr share elas
  • 用Python完成寻找水仙花数

    首先说一下我是Python的初学者 如果有任何不正确或可以改进的地方 请大家多多包容 所谓 水仙花数 是指一个三位数 其各位数字的立方和等于该数本身 例如153 1 3 5 3 3 3 理解了题意后我们就可以明白找到水仙花的重点就在于将一个
  • R2_A_Taming the Herd

    题面 Taming the Herd Early in the morning Farmer John woke up to the sound of splintering wood It was the cows and they we
  • java中值传递和引用传递

    目录 值传递 引用传递 Java 中有两种数据类型 请谈一下值传递与引用传递 Java 中只有值传递么 值传递 package com github hcsp public class Main public static void mai