Java中为什么只有值传递?

2023-11-03

开始之前,我们先来搞懂下面这两个概念:

  • 形参&实参
  • 值传递&引用传递

形参&实参

方法的定义可能会用到 参数(有参的方法),参数在程序语言中分为:

  • 实参(实际参数) :用于传递给函数/方法的参数,必须有确定的值。
  • 形参(形式参数) :用于定义函数/方法,接收实参,不需要有确定的值。
String hello = "Hello!";
// hello 为实参
sayHello(hello);
// str 为形参
void sayHello(String str) {
    System.out.println(str);
}

 一、   值传递&引用传递

程序设计语言将实参传递给方法(或函数)的方式分为两种:

  • 值传递 :方法接收的是实参值的拷贝,会创建副本。
  • 引用传递 :方法接收的直接是实参所引用的对象在堆中的地址,不会创建副本,对形参的修改将影响到实参。

很多程序设计语言(比如 C++、 Pascal )提供了两种参数传递的方式,不过,在 Java 中只有值传递。

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

不需要太多废话,我通过 3 个例子来给大家证明。

案例1:传递基本类型参数

代码:

public static void main(String[] args) {
    int num1 = 10;
    int num2 = 20;
    swap(num1, num2);
    System.out.println("num1 = " + num1);
    System.out.println("num2 = " + num2);
}

public static void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
    System.out.println("a = " + a);
    System.out.println("b = " + b);
}

输出:

a = 20
b = 10
num1 = 10
num2 = 20

解析:

在 swap() 方法中,ab 的值进行交换,并不会影响到 num1num2。因为,ab 的值,只是从 num1num2 的复制过来的。也就是说,a、b 相当于 num1num2 的副本,副本的内容无论怎么修改,都不会影响到原件本身。

 

通过上面例子,我们已经知道了一个方法不能修改一个基本数据类型的参数,而对象引用作为参数就不一样,请看案例2。

案例2:传递引用类型参数1

代码:

	public static void main(String[] args) {
      int[] arr = { 1, 2, 3, 4, 5 };
      System.out.println(arr[0]);
      change(arr);
      System.out.println(arr[0]);
	}

	public static void change(int[] array) {
      // 将数组的第一个元素变为0
      array[0] = 0;
	}

输出:

1
0

解析:

 

看了这个案例很多人肯定觉得 Java 对引用类型的参数采用的是引用传递。

实际上,并不是的,这里传递的还是值,不过,这个值是实参的地址罢了!

也就是说 change 方法的参数拷贝的是 arr (实参)的地址,因此,它和 arr 指向的是同一个数组对象。这也就说明了为什么方法内部对形参的修改会影响到实参。

为了更强有力地反驳 Java 对引用类型的参数采用的不是引用传递,我们再来看下面这个案例!

案例3 :传递引用类型参数2

public class Person {
    private String name;
   // 省略构造函数、Getter&Setter方法
}

public static void main(String[] args) {
    Person xiaoZhang = new Person("小张");
    Person xiaoLi = new Person("小李");
    swap(xiaoZhang, xiaoLi);
    System.out.println("xiaoZhang:" + xiaoZhang.getName());
    System.out.println("xiaoLi:" + xiaoLi.getName());
}

public static void swap(Person person1, Person person2) {
    Person temp = person1;
    person1 = person2;
    person2 = temp;
    System.out.println("person1:" + person1.getName());
    System.out.println("person2:" + person2.getName());
}

输出:

person1:小李
person2:小张
xiaoZhang:小张
xiaoLi:小李

解析:

怎么回事???两个引用类型的形参互换并没有影响实参啊!

swap 方法的参数 person1 和 person2 只是拷贝的实参 xiaoZhang 和 xiaoLi 的地址。因此, person1 和 person2 的互换只是拷贝的两个地址的互换罢了,并不会影响到实参 xiaoZhang 和 xiaoLi 。

 

总结

Java 中将实参传递给方法(或函数)的方式是 值传递 :

  • 如果参数是基本类型的话,很简单,传递的就是基本类型的字面量值的拷贝,会创建副本。
  • 如果参数是引用类型,传递的就是实参所引用的对象在堆中地址值的拷贝,同样也会创建副本。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中为什么只有值传递? 的相关文章

随机推荐

  • Altium designer10---PCB添加Logo

    安全之安全 security 博客目录导读 目录 1 生成bmp后缀的图片 画图打开 调整大小 生成bmp 2 生成PCB Logo PCB Logo Creator 图标生成器 Load加载 Convert转换 3 复制到所制作板子的PC
  • python基础八:函数

    1 函数简介 1 1语法 语法 def 函数名 形参1 形参2 形参3 代码块 函数名 调用函数 1 2介绍 函数是个对象 function 函数用来保存一些可执行的代码 在你需要的时候可以对这些语句进行多次调用 函数中保存的代码不会立即执
  • Sublime Text 4 汉化 安装Install Package Mac 安装插件

    1 下载安装包Sublime Text 4 官网选择安装包下载 下载完成直接打开 下载应用程序 运行应用程序 2 Sublime Text 4 跳过 不需要 安装Install Package工具 Text 4 不需要安装Package工具
  • Description:Web server failed to start. Port 8080 was already in use.

    APPLICATION FAILED TO START Description Web server failed to start Port 8080 was already in use Action Identify and stop
  • 顺序表——简单实现(静态数组)

    实现基于静态数组的顺序表的以下基本操作 1 初始化 2 尾插 3 尾删 4 头插 5 头删 6 读任意位置元素 7 修改任意位置元素 8 查找指定元素值的下标 9 在任意位置插入元素 实现环境 Centos6 5 vim编辑器 大体的思路
  • web前端字体居中_css文字居中怎么弄?

    CSS是一种定义样式结构如字体 颜色 位置等的语言 被用于描述网页上的信息格式化和现实的方式 下面我们来看一下css设置文字居中的方法 css可以通过为文字所在标签添加text align center样式使文字居中 text align属
  • git冲突在eclipse、idea、sourceTree上的解决方法

    一 使用eclipse时 情形一 用户1编辑A文件并提交 用户2未拉取最近代码也编辑A文件产生的冲突 用户2未提交本地仓库时 1 进入同步页面 注意 只有一个向下箭头表示未提交本地仓库 2 拉取远程文件 双击冲突文件减去编辑 将右侧代码合并
  • IT实习技能提升第一篇

    文章目录 前言 一 Git 1 基础配置 2 老板让去git上拉取代码 3 更改完代码后上推 二 QT使用步骤 1 注册QT账号挺有必要 2 同时运行两个项目 总结 前言 新入职的码农 嵌入式软件方向 提示 以下是本篇文章正文内容 下面案例
  • IOS小白入门指南

    加入ios 项目已经一个多月了 本篇文章主要介绍IOS开发入门的一些基础知识 帮助想学习iOS开发的人更有效率地学习 目录 需要的计算机基础 开发语言选择 IOS两种开发语言的异同 Objective C和swift的相同点 二者的不同点
  • 关于webview加载网页,返回后总是刷新页面问题解决

    最近用webview发现返回上个页面总是又自动刷新页面 我的需求是进入下页的时候不用缓存 而返回上个页面的时候不要刷新页面回到顶部 要保持在原来页面进入下页的位置 首先来了解一下webview加载网页的几个模式 即websetting中设置
  • 【AI视野·今日CV 计算机视觉论文速览 第211期】Wed, 2 Jun 2021

    AI视野 今日CS CV 计算机视觉论文速览 Wed 2 Jun 2021 Totally 63 papers 上期速览 更多精彩请移步主页 Interesting YOLOS You Only Look at One Sequence 纯
  • 冲击python二级——python的安装,IDLE的一般操作,PIP包管理使用,变量基础

    现在大部分的教程 都会要求直接安装Anaconda 和Pycharm 虽然pycharm是非常优秀的python IDE生产工具 但是对于新手来说配置比较繁琐 并不友好 而且国考计算机二级 只能用python自带的idle 用pip包管理安
  • 大数据——基于Spark Streaming的流数据处理和分析

    基于Spark Streaming的流数据处理和分析 流是什么 为什么需要流处理 流处理应用场景 如何进行流处理 Spark Streaming简介 Spark Streaming流数据处理架构 Spark Streaming内部工作流程
  • 实验室项目——连接mysql服务器报错(驱动版本不一致)

    mysql right syntax to use near OPTION SQL SELECT LIMIT 15 at line 1 问题描述 OPTION SQL SELECT LIMIT XXX 问题原因 项目使用的mysql驱动和m
  • 集线器、交换机和路由器(图解)

    一 物理层 使用 MAC 解决设备的身份证问题 1 通信的原始时代 很久很久之前 你不与任何其他电脑相连接 孤苦伶仃 直到有一天 你希望与另一台电脑 B 建立通信 于是你们各开了一个网口 用一根网线连接了起来 用一根网线连接起来怎么就能 通
  • UEFI/Legacy bios简介与grub安装教程

    目录 一 BIOS简介 二 UEFI与Legacy 启动模式简介 Legacy启动模式 UEFI启动模式 具体不同 三 grub安装 grub软件包的安装 grub源码下载 grub本地编译安装及使用 Ubuntu 环境下 四 参考 一 B
  • 华为机试-8.计算面积(绘图机器的绘图笔初始位置在原点)

    计算面积 绘图机器的绘图笔初始位i在原点 0 0 机器启动后其绘图笔按下面规则绘制直线 1 尝试沿着横向坐标轴正向绘制直线 直到给定的终点值E 2 期间可通过指令在纵坐标轴方向进行偏移 井同时恰制直线 偏移后按规则1绘制直线 指令的格式为X
  • chatgpt赋能python:Python输出中出现的None值:问题、解释和解决方案

    Python输出中出现的None值 问题 解释和解决方案 在Python编程中 经常会出现输出中包含None值的情况 这会给程序员带来一些困扰 因为它可能会在应用程序中导致错误或不正确的结果 在本篇文章中 我们将探寻这个问题的原因 介绍有关
  • Cascade EF-GAN: 局部聚焦渐进式面部表情编辑

    目前面部表情编辑存在的问题 生成性对抗网络 GAN 的最新进展表明 面部表情编辑有了显著的改进 然而 当前的方法仍然容易在表达密集型区域周围产生伪影和模糊 并且在处理大间隙表达转换 例如从愤怒到大笑的转换 时 经常引入不希望的重叠伪影 本文
  • Java中为什么只有值传递?

    开始之前 我们先来搞懂下面这两个概念 形参 实参 值传递 引用传递 形参 实参 方法的定义可能会用到 参数 有参的方法 参数在程序语言中分为 实参 实际参数 用于传递给函数 方法的参数 必须有确定的值 形参 形式参数 用于定义函数 方法 接