java到底是引用传递还是值传递?
今天我们来讲讲一个在学习中容易误解的问题,面试中也偶尔问到,java方法调用时到底是值传递还是引用传递?
首先,请大家来做一个判断题,下面的3个问题是否描述正确
1. java基本数据类型传递是值传递,引用数据类型是引用传递
2. java都是引用传递
3. 方法调用时传的是数据值就是指传递,传的是地址就是引用传递
我们暂且不直说上面3个问题的正确性,下面,我们通过几个测试案例来测试一下参数传递
1. 基本数据类型当作参数
- public class test1 {
- public static void main(String[] args) throws Exception {
- int a = 10;
- change(a);
- System.out.println("a = " + a);
- }
- public static void change(int s) {
- s = 20;
- System.out.println("s = " + s);
- }
- }
运行结果: 方法执行后,没有改变原有a的值
s = 20
a = 10
2. 引用类型当作参数
- public class Student {
- private String name; //姓名
- Student(String name){
- this.name = name;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- public class Test1{
public static void main(String[] args) throws Exception {
Student s = new Student("haly");
change(s);
System.out.println("s = " + s.getName());
}
public static void change(Student x) {
x.setName("wuwu");
System.out.println("x = " + x.getName());
}
}
运行结果: 方法执行后,改变了原来s的值
x = wuwu
s = wuwu
看到这里,很多同学就觉得问题1答案是正确的, java基本数据类型传递是值传递,引用数据类型是引用传递,但是真的是这样吗?
这里我可以提前透露下答案,上面这个测试之所以改变了原来实参s里面的值,是因为我们传递到方法的都是实参对象的一个拷贝,x对象是s对象引用的一个拷贝,
所以x和s都是指向同一块内存地址,改变x里面的值,相当于改变s的值,因为传的是对象引用的拷贝,而不是对象引用本身,所以是值传递。
如果不好理解,我给大家举个例子:
我有一辆车,我自己有一把车钥匙,有一天我的女朋友想要开车,我就配制了一把车钥匙给她,这时候,相当于方法调用,传递了一把钥匙的拷贝给她。
她在钥匙上刻字,对我的钥匙是没有影响的,但是她拿钥匙打开车,将我的车坐垫换了,我开这辆车的时候,车坐垫的确是换掉了,这是同一个道理。
如果还不清楚,我用两张图,分别表示案例1和案例2的值传递:
案例1 案例2
如果大家还不好理解,下面我就写一个案例3,让大家更加清晰的看出,java是值传递
3. 引用类型当作参数
- public class Test1 {
- public static void main(String[] args) throws Exception {
- Student s1 = new Student("小张");
- Student s2 = new Student("小李");
- Test1.swap(s1, s2);
- System.out.println("s1:" + s1.getName() + ",s2:" + s2.getName());
- }
- public static void swap(Student x, Student y) {
- Student temp = x;
- x = y;
- y = temp;
- System.out.println("x:" + x.getName() + ",y:" + y.getName());
- }
- }
运行结果:
x:小李,y:小张
s1:小张,s2:小李
通过测试3的代码,我们可以看出,在方法中交换了两个参数的值,但是原来的值并没有交换,如果是引用传递的话,我们操作的都是实参本身的引用,按理也会交换的。
下面,我们通过一个图在仔细思考一下答案:我们交换了x和y对象的引用,对原来的s1和s2并没有影响。
通过以上代码及图描述,我们可以得出如下2个结论:
1. 如果我们传递的实参是对象引用的拷贝,就是值传递,如果我们传递的实参是引用本身,就是引用传递。
2. 在java中,不管基本数据类型,还是引用类型,都是值传递。
如有不正确的地方,欢迎大家批评指出,一起进步~~
java到底是引用传递还是值传递?的更多相关文章
- 理解Java中的引用传递和值传递
关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习 ...
- Java Object 引用传递和值传递
Java Object 引用传递和值传递 @author ixenos Java没有引用传递: 除了在将参数传递给方法(或函数)的时候是"值传递",传递对象引用的副本,在任何用&q ...
- (转载)理解Java中的引用传递和值传递
关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天 ...
- Java中的引用传递和值传递
Java中的引用传递和值传递 关于Java的引用传递和值传递,在听了老师讲解后,还是没有弄清楚是怎么一回事,于是查了资料,所以在这里与大家分享,有不对的地方,欢迎大家留言. java中是没有指针的,j ...
- Java中没有引用传递只有值传递(在函数中)
◆传参的问题 引用类型(在函数调用中)的传参问题,是一个相当扯的问题.有些书上说是传值,有些书上说是传引用.搞得Java程序员都快成神经分裂了.所以,我们最后来谈一下“引用类型参数传递”的问题. 如下 ...
- Java千百问_05面向对象(011)_引用传递和值传递有什么差别
点击进入_很多其它_Java千百问 1.什么是值传递 值传递,是将内存空间中某个存储单元中存放的值,传送给还有一个存储单元.(java中的存储单元并不是物理内存的地址,但具有相关性) 比如: //定义 ...
- java引用传递和值传递
关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习 ...
- Java当中的内存分配以及值传递问题内存解析
首先必须说明作为Java程序员对于内存只要有大致的了解就可以了,如果你对Java当中的某一个知识点在不需要分析内存分配过程的情况下可以掌握,那就大可不必去研究内存.如果你对知识点已经掌握,那么你应该把 ...
- effective c++:引用传递与值传递,成员函数与非成员函数
以pass-by-reference-to-const 替换pass-by-value 考虑以下class继承体系 class Person { public: Person(); // parame ...
随机推荐
- AspnetCore 缓存篇
AspnetCore 缓存篇 一.缓存的作用 怎样理解缓存: 其实所有的程序,架构,优化,线程...等技术手段,最终的目的都是如何使产品快速的响应用户的操作,提高用户的体验性,目标都是为了系统的使用者 ...
- Java基础:内存模型
1. 引言 2. Java内存模型 3. 内存间的交互操作 1. 引言 考虑到计算机组成的内容: 原始的计算机是CPU用于计算+硬盘用于存储,由于CPU的高速发展和硬盘的缓慢发展,高速的存储需要持续供 ...
- Java多线程:wait(),notify(),notifyAll()
1. wait(),notify(),notifyAll() 2. wait() 2.1. wait() 2.2. wait(long timeout) 2.3. wait(long timeout, ...
- CentOS 6 安装HBase集群教程
hbase0.99.2安装包下载(链接:https://pan.baidu.com/s/1dR-HB3P6mzsXVW6sLI8uxQ 密码:4g1n) 首先需要安装 zookeeper(点击查看) ...
- Vue中的scoped及穿透方法
何为scoped? 在vue文件中的style标签上,有一个特殊的属性:scoped.当一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,也就是说,该样式只能适用于当前组 ...
- 工作中常用的JS函数整理分享(欢迎大家补充)
今年在渣X工作整理的常用JS函数 今年来了渣X工作,我所在这个部门分工很奇怪,CSS竟然有专门的人在搞,开发PHP的人员需要处理JS,以至于有时候开发起来不是那么得心应手,感觉把JS和CSS拆开就像是 ...
- IntelliJ IDEA maven 构建简单springmvc项目
环境: apache-tomcat-8.5.15 jdk1.8.0_172 IDEA 建立一个maven-webapp项目:Create New Project 后点击next 然后next 可以选择 ...
- python3 爬去QQ音乐
import requests import re import json import os def get_name(singer): url = 'https://c.y.qq.com/soso ...
- 二十六、Hadoop学习笔记————Hadoop Yarn的简介复习
1. 介绍 YARN(Yet Another Resource Negotiator)是一个通用的资源管理平台,可为各类计算框架提供资源的管理和调度. 之前有提到过,Yarn主要是为了减轻Hadoop ...
- 网络模型 - 每天5分钟玩转 Docker 容器技术(169)
本节我们讨论 Kubernetes 网络这个重要主题. Kubernetes 作为编排引擎管理着分布在不同节点上的容器和 Pod.Pod.Service.外部组件之间需要一种可靠的方式找到彼此并进行通 ...