Java是值传递还是引用传递
观点:Java没有引用传递,只有值传递
基本概念
- 实参:实际参数,是提前准备好并赋值完成的变量。分配到栈上。如果是基本类型直接分配到栈上,如果是引用类型,栈上分配引用空间存储指向堆上分配的对象本身的指针。String等基本类型的封装类型比较特殊,后续讨论。
- 形参:形式参数,方法调用时在栈上分配的实参的拷贝。
- 值传递:方法调用时,实际参数把它的值传递给对应的形式参数,形参接收的是原始值的一个拷贝,此时内存中存在两个相等的变量
- 引用传递:方法调用时将实参的地址传递给对应的形参,实参和形参指向相同的内容
Java数据有两个类型
- 基本类型
- 引用类型
基本类型
如上图所示,基本类型传递时,线程在栈上分配形式参数并拷贝实际参数的值。
/** * Create with IntelliJ IDEA * Author : wangzhenpeng * Date : 2018/4/8 * Time : 上午9:48 * E-mail : wangzhenpeng0924@163.com * Description : Test */ public class Test { public static void main(String[] args) { int value = 100; change(value); System.out.println("outer: " + value); } static void change(int value) { value = 200; System.out.println("inner: " + value); } }
结果输出:
inner: 200 outer: 100
方法修改的只是形式参数,对实际参数没有作用。方法调用结束后形式参数随着栈帧回收。
引用类型
如上图所示,引用类型传递时,传递的是引用的值,从这个角度来讲还是值传递。如果是引用传递的话,传递的应该是引用的地址,而不是引用的值。
/** * Create with IntelliJ IDEA * Author : wangzhenpeng * Date : 2018/4/8 * Time : 上午9:48 * E-mail : wangzhenpeng0924@163.com * Description : Test */ public class Test { public static void main(String[] args) { Person person = new Person(); person.setAge(17); person.setName("Tom"); change(person); System.out.println("outer: " + person.getAge()); } static void change(Person value) { value.setAge(18); System.out.println("inner: " + value.getAge()); } static class Person { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } }
结果输出:
inner: 18 outer: 18
方法修改的是引用所指向的数据空间的数据,所以方法外部也能看到修改的结果。
基本类型的数组也是对象,所以int[] 传递的也是对象应用的值。
/** * Create with IntelliJ IDEA * Author : wangzhenpeng * Date : 2018/4/8 * Time : 上午9:48 * E-mail : wangzhenpeng0924@163.com * Description : Test */ public class Test { public static void main(String[] args) { int[] intArray = new int[10]; change(intArray); System.out.println("outer: " + intArray[0]); } static void change(int[] value) { value[0] = 200; System.out.println("inner: " + value[0]); } }
运行结果:
inner: 200 outer: 200
如果对引用类型的传递稍作修改
static void change(Person value) { value = new Person(); value.setAge(18); System.out.println("inner: " + value.getAge()); }
运行结果:
inner: 18 outer: 17
用图解释为:
同理String,Integer等类型的封装类型为final类型,对数据的修改操作实际上是创建了一个新的对象
/** * Create with IntelliJ IDEA * Author : wangzhenpeng * Date : 2018/4/8 * Time : 上午9:48 * E-mail : wangzhenpeng0924@163.com * Description : Test */ public class Test { public static void main(String[] args) { String value = "123"; change(value); System.out.println("outer: " + value); } static void change(String value) { value = "abc"; System.out.println("inner: " + value); } }
运行结果:
inner: abc outer: 123
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
区块链开发(零)如何开始学习以太坊及区块链
一、 以太坊和区块链的关系 从区块链历史上来说,先诞生了比特币,当时并没有区块链这个技术和名词,然后业界从比特币中提取了技术架构和体系,称之为区块链技术。从比特币提取的区块链技术称之为区块链1.0时代,那个时候的应用主要以电子货币和去中心化交易为主,比如各种山寨币。而以太坊将区块链带入了2.0的时代,区块链2.0不是推翻了1.0,而是在1.0的基础上实现了区块知晓、价值知晓、图灵完备,并进行了细节优化,从而形成了以智能合约为特色的区块链2.0。比特币定位于一个应用,而以太坊定位于平台,你可以在这个平台上利用智能合约做各种应用。 所以,学习区块链,直接学习以太坊就好了 二、 以太坊入门的方法 对于没有接触过区块链的人,建议先参会以太坊的日常应用。 1、 使用客户端 这里的教程
- 下一篇
What Is ElectronJS and Why Should You Use It?
By Sai Sarath Chandra, Alibaba Cloud Tech Share Author and Alibaba Cloud MVP Before we talk about ElectronJS, we need to take a step back and see how Desktop applications are made. We will also analyze the issues with the current way of developing Desktop applications. After that, we will explore how to create a fully functional invoice application backend using Electr
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS7,8上快速安装Gitea,搭建Git服务器