Java基础面试题02:简述什么是值传递和引用传递?

embedded/2024/11/24 21:51:43/

面试题:简述什么是值传递和引用传递?

什么是值传递?

值传递(pass by value)是指在调用函数时,把实际参数的值复制一份传递给函数。换句话说,函数内部对参数的任何修改,都不会影响到原始的实际参数。这是因为传递的是“副本”,跟原值没直接联系。

举个例子:

func GetA(b int) int {b++  // 改的是 b 的副本return b
}func main() {a := 1resultA := GetA(a)  // a 的值被复制到 bfmt.Println(resultA)  // 输出 2fmt.Println(a)        // a 还是 1
}

在这个例子中,a的值被复制了一份传给函数GetA,所以函数内部的修改不会影响到外面的a


什么是引用传递?

引用传递(pass by reference)是指直接将实际参数的“地址”传递给函数。函数内的参数变动,会直接影响到实际参数的值,因为函数操作的是原始的“引用”而不是副本。

然而!许多编程语言(比如 Java 和 Go)其实并不是严格意义上的引用传递。它们传递的依然是“值”,只不过这个“值”可能是对象的引用(也就是内存地址的副本)。这点是很多人容易误解的地方。


常见误解,别踩坑!

  1. “值传递是传值,引用传递是传引用。”
    误!问题的关键不在传的是什么,而在于“传递的值有没有被复制”。

  2. “Java 是引用传递。”
    错!Java 传的是引用的副本,是“值传递”。复制了引用,实际参数地址不会被直接修改。

  3. “传递基本类型是值传递,传递对象是引用传递。”
    依然错!语言本质还是值传递,传对象时是引用的值被复制,而不是直接传递引用。


再补充点知识:特殊的“传共享对象调用”

传共享对象有点像引用传递的“拐弯版”。实际参数的地址被复制一份传给函数,操作的是复制后的地址,最后依然指向原始的值。你要改这个值完全没问题,但如果试图改引用本身的指向,就没用。


求值策略的简单解释

求值策略决定了参数在函数调用时是怎么被处理的。这里补充一下最常见的几种:

  1. 传值调用(值传递):
    直接复制参数的值,函数内部改动对实际参数无影响。

  2. 传引用调用(引用传递):
    传的是参数的引用,函数内改动会直接反映到原始参数上。

  3. 传共享对象调用(共享对象传递):
    传递对象的引用副本,操作引用指向的值有效,改引用本身无效。


编程语言中的值传递 VS 引用传递

Go 语言的例子

package mainimport "fmt"func GetB(b int) {b++  // 改的是 b 的副本
}func main() {b := 1GetB(b)fmt.Println(b)  // b 还是 1,因为改的是副本
}

还有字符串的例子:

func subString(str string, start int, end int) (*string, string) {var s = &strsubStr := str[start:end]return s, subStr
}func main() {str := "123,我们"_, result := subString(str, 0, 3)fmt.Println(result)  // 输出 "123"
}

Go 永远是值传递,哪怕传递的是引用,还是复制了引用的副本。


Java 的例子

java">public class Main {public static void main(String[] args) {int a = 1;int b = getA(a);System.out.println(b); // 输出 2System.out.println(a); // a 还是 1}public static int getA(int b) {b++; // 改的是 b 的副本return b;}
}

字符串的例子:

java">public class Main {public static void main(String[] args) {String s = "123,我们";String result = subString(s);System.out.println(result); // 输出 "123"}public static String subString(String str) {return str.substring(0, 3); // 截取字符串,返回一个新字符串}
}

Java 的参数传递本质也是值传递,传递对象时传的是“引用的副本”。


小总结

  • 值传递:传递的是参数的值,函数内修改对实际参数无影响。
  • 引用传递:传递的是参数的引用,函数内修改直接影响实际参数。
  • **Java 和 Go 的参数传递:**都是值传递。传递的可能是值的副本,也可能是引用的副本,但一定是“复制”过的东西。

记住这个逻辑,搞清“传的内容有没有被复制”,以后面试再也不慌啦!

最后说一句(求关注,求赞,别白嫖我)

最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的
7701页的BAT大佬写的刷题笔记,让我offer拿到手软

本文,已收录于,我的技术网站 cxykk.com:程序员编程资料站,有大厂完整面经,工作技术,架构师成长之路,等经验分享

求一键三连:点赞、分享、收藏

点赞对我真的非常重要!在线求赞,加个关注我会非常感激!


http://www.ppmy.cn/embedded/140217.html

相关文章

SpringBoot3+Jasypt如何在配置文件中对数据库的密码进行加密以防止密码泄露

在 Spring Boot 3 中,可以通过jasypt-spring-boot-starter对配置文件中的数据库密码或者其他重要密码进行加密,操作非常简单,可以有效防止密码泄露: 1. 使用 Jasypt 加密 添加依赖 在 pom.xml 中添加 Jasypt 依赖: …

Word Embedding

Word Embedding 一 基本概述二 word embedding可视化 哈喽,小伙伴们!今天聊一聊自然语言处理(NLP)中的一个小概念.语料的数值化转化.因为有一定了解的小伙伴应该都知道在NLP中,汉字是没办法直接送到模型训练的,因为计算机只能识别二进制的数据.所以我们需要把汉字转成张量的形式…

电脑自动关机时间如何定?Wise Auto Shutdown 设置关机教程

在日常使用电脑的过程中,有时我们需要让电脑在特定的时间自动关机,比如在下载大文件完成后、执行长时间的任务结束时,或者只是单纯想在某个预定时间让电脑自动关闭以节省能源。这时候,Wise Auto Shutdown 这款软件就能派上大用场了…

播放器开发之ffmpeg 硬件解码方案

硬件编解码的概念 硬件编解码是⾮CPU通过烧写运⾏视频加速功能对⾼清视频流进⾏编解码,其中⾮CPU可包括GPU、FPGA或者 ASIC等独⽴硬件模块,把CPU⾼使⽤率的视频解码⼯作从CPU⾥分离出来,降低CPU的使⽤负荷,使得平台能 ⾼效且流畅…

[译]Elasticsearch Sequence ID实现思路及用途

原文地址:https://www.elastic.co/blog/elasticsearch-sequence-ids-6-0 如果 几年前,在Elastic,我们问自己一个"如果"问题,我们知道这将带来有趣的见解: "如果我们在Elasticsearch中对索引操作进行全面排序会怎样…

error Unexpected ‘debugger‘ statement no-debugger

[eslint] D:\System File\Desktop\后台\test\test\src\components\HelloWorld.vue 19:5 error Unexpected debugger statement no-debugger ✖ 1 problem (1 error, 0 warnings) You may use special comments to disable some warnings. Use // eslint-disable-next-li…

线性代数(第六章:二次型)

一、二次型的基础知识 1. 二次型 定义:含有 n 个变量 x1 , x2 ,…, xn 的二次齐次函数 f = a11x12 + a22x22 + … + annxn2 + 2a12x1x2 + 2a13x1x3 + … + 2a(n-1),nxn-1xnf = xTAx(AT = A),x = (x1 , x2 ,…, xn)Tf = Σi=1nΣj=1n aijxixj称 A 是二次型的矩阵,r(A) 是…

基于Java Springboot高校教务管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…