写在开头

Java是值传递还是引用传递?这个问题几乎100%的出现在了各大主流Java面试题中,知识点很小,但很考验面试者对于Java运行的理解,今晚趁着生产投产的空子,过来小聊一下。

实参与形参

所谓的值传递or引用传递是指方法在调用的过程中实参传递的两种变现形式,那么好,想搞清楚这个问题的前提是,先搞清楚实参形参

实际参数(实参,英文:Arguments):用于传递给函数/方法的参数,必须有确定的值!

形式参数(形参,英文:Parameters):用于定义函数/方法,接收实参,不需要有确定的值。

int a = 10;
//这里传入的a为实参,有实际确认的值:10
sum(a);
//这里方法定义中的参数为形参,无需确认值,在方法调用中用来接收实际参数
void sum(int p){
System.out.println(p+10);
}

值传递与引用传递

为了充分调用大家的思考,这里先不给结论,先上几段代码示例,通过分析代码,最终得出结果,这是个人最喜欢的总结方式!

【代码示例1-基本数据类型的参数传递】

public class Test {
public static void main(String[] args) {
int a = 1;
int b = 2;
swap(a, b);
System.out.println("实参a = " + a);
System.out.println("实参b = " + b);
}
public static void swap(int p1, int p2) {
int temp = p1;
p1 = p2;
p2 = temp;
System.out.println("p1 = " + p1);
System.out.println("p2 = " + p2);
}
}

输出:

p1 = 2
p2 = 1
实参a = 1
实参b = 2

分析:

在swap()方法中,我们将p1,p2参数的值进行了互换,但这并没有影响实参a,b的值,因为在传入方法时,只是对a,b的值做了拷贝,拷贝之后,他们之间的关系互相独立,这就是值传递!

【代码示例2-引用类型的参数传递】

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

输出:

1
0

分析:

初始化一个引用类型的数组arr作为实参,在change方法中我们将数组的0位数值进行了重新赋值,将实参传入方法执行后,我们可以看到实参的第0位数值已经被成功修改为0,看上去是不是像引用传递?

实则不然!请看下面的示意图:

我们知道实参arr是一个对象的引用,而在调用change()时将实参传进来,其实是拷贝了一份实参的引用地址过来,而这个时候实现与形参,他们会执行对象数据对象的同一个地址,导致我们在修改形参的数组值时,实参的0位数值也发生了改变,毕竟他们指向的是同一对象!

【代码示例3-String的参数传递】

public class Test{
public static void main(String[] args) {
Test test= new Test();
// String类
String s = "hello";
test.pass(s);
System.out.println("s = " + s);
}
public void pass(String str) {
str = "world";
System.out.println("str = "+ str);
}
}

输出:

str = world
s = hello

分析:

看到这个结果时,是不是有点出乎意料,在示例2中我们得知,引用类型时的参数传递,拷贝的是引用地址的值,实参会随着形参的改变而改变,但这一段代码的输出显然不符合预期,这是为什么?

看过俺之前写的文章的朋友应该是清楚的,虽然String也是引用类型,但它是不可变类,一旦对赋值完成,就改变不聊了,这也就意味着,上述代码中的两次字符串赋值,分别操作的是两个String对象,两者毫无关联!

String的详细描述,可以看一下这篇文章:一文看完String的前世今生

总结

看完了如上的例子,大家对Java的参数传递有没有更深的了解了呢,通过上面的几个例子我们可以得出这样的总结:

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

如果参数是基本类型的话,很简单,传递的就是基本类型的字面量值的拷贝,会创建副本。

如果参数是引用类型,传递的就是实参所引用的对象在堆中地址值的拷贝,同样也会创建副本。

每日一道Java面试题:Java是值传递还是引用传递?的更多相关文章

  1. 一道笔试题来理顺Java中的值传递和引用传递

      题目如下: private static void change(StringBuffer str11, StringBuffer str12) { str12 = str11; str11 = ...

  2. java面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

    答:是值传递.Java编程语言只有值传递参数. 当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本.指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用 ...

  3. 堆栈详解 + 彻底理解Java的值传递和引用传递

    本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...

  4. Java的值传递和引用传递的说法

    学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨论的话题又是充满争议:有的论坛帖子说Java ...

  5. java中方法的参数传递机制(值传递还是引用传递)

    看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  答:是值传递.Java 编程语言只有值传递参 ...

  6. java参数传递时到底是值传递还是引用传递

    java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...

  7. 面试官:兄弟,说说Java到底是值传递还是引用传递

    二哥,好久没更新面试官系列的文章了啊,真的是把我等着急了,所以特意过来催催.我最近一段时间在找工作,能从二哥的文章中学到一点就多一点信心啊! 说句实在话,离读者 trust you 发给我这段信息已经 ...

  8. Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义

    一.Java中什么叫做引用类型变量?引用:就是按内存地址查询       比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...

  9. java中值传递和引用传递

    最近工作中使用到了值传递和引用传递,但是有点懵,现在看了下面的文章后清晰多了.一下是文章(网摘) 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...

  10. Java中的值传递和引用传递

    这几天一直再纠结这个问题,今天看了这篇文章有点思路了,这跟C++里函数参数为引用.指针还是有很大区别. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里 ...

随机推荐

  1. Spring Boot Admin 查看 Client 日志

    日志配置如下:如何将不同业务模块产生的日志 分多文件记录 此时 Spring Boot Admin 中看不了 Client 的日志 Logfile ViewerBy default the logfi ...

  2. Mac问题记录

    1. "App" can't be opened because Apple cannot check it for malicious software. 一般来说,在Syste ...

  3. OOALV总结

    1.1ALV屏幕 1.1.1定义无CONTAINER屏幕 1.屏幕中可以不使用定制控制控件画范围,直接定义一个屏幕即可. "--------------------------------- ...

  4. Spring 学习笔记(2)框架介绍

    本篇文章主要对 Spring 框架进行整体介绍,包括其核心功能模块与体系结构,让大家对该框架有个大体的认识. 1. 前景提要 如果你之前学过 Servlet 的话,那么一定会对 MVC 分层概念有所了 ...

  5. BZOJ 3450 - Tyvj1952 Easy (期望DP)

    描述 某一天 WJMZBMR 在打 osu~~~ 但是他太弱逼了,有些地方完全靠运气:( 我们来简化一下这个游戏的规则: 有 \(n(n\le 300000)\) 次点击要做,成功了就是 o,失败了就 ...

  6. C#商品金额大小写转换

    见图 代码如下 public string NumToChinese(string x) { //数字转换为中文后的数组 string[] P_array_num = new string[] { & ...

  7. andriod sdk安装与使用

    一.进入以下网站下载 https://www.androiddevtools.cn/ 选择sdk工具-sdktools,这个工具比较好,可以通过SDK Manager下载到各种想要的包 有zip与ex ...

  8. 概率图模型 · 概率论基础 | 讲的非常好的 KL 散度博客

    知乎博客链接:https://zhuanlan.zhihu.com/p/425693597 感觉讲的非常好,谢谢善良的博主

  9. FGC频繁导致CPU 飙升定位及JVM配置优化总结

    本文为博主原创,未经允许不得转载: 目录: 1. 定位消耗cpu 的服务进程和线程 2. 定位FGC 的原因 3. 定位jvm 参数是否导致FGC 4. 调试最优解的 jvm 配置 描述:项目中存在一 ...

  10. /etc/profile,/etc/bashrc,~/.profile,~/.bashrc 的区别及使用

    转载请注明出处: /etc/profile  为系统的全局环境变量设置,此文件为系统的每个用户设置环境信息    /etc/bashrc 为每一个运行bash shell的用户执行此文件.当bash ...