基本类型、包装类型、引用类型、String等作为实参传递后值会不会改变?

简介: 基本类型、包装类型、String类型作为参数传递之后,在方法里面修改他们的值,原值不会改变!引用类型不一定,要看是怎么修改它的。

[1] 先说结论


 基本类型、包装类型、String类型作为参数传递之后,在方法里面修改他们的值,原值不会改变!引用类型不一定,要看是怎么修改它的。


[2] 为什么基本类型、包装类型、String类型传参之后原值不会变?


[2.1] 基本类型:


 通常情况下,Java 基本数据类型变量在 JVM 中的存储方式是将其存储在栈(Stack)中。


 栈用于存储方法执行时的局部变量、操作数栈和方法返回值等。


 当程序运行到一个方法时,JVM 会为该方法创建一个栈帧(Stack Frame),并将该栈帧压入栈顶。栈帧中会包含该方法的局部变量表(Local Variable Table)、操作数栈(Operand Stack)等信息。


 在局部变量表中,JVM 会为每个基本数据类型变量分配一定的存储空间,并将其存储在栈帧中。例如,一个 int 类型的变量需要 4 个字节的存储空间,JVM 会在局部变量表中分配 4 个字节的空间,并将其用于存储该变量的值。类似地,其他基本数据类型变量在局部变量表中也会分配相应大小的存储空间。



 当基本类型变量作为形参传递给方法时,发生了以下步骤:


 1、在调用方法时,将实参的值复制一份,传递给形参。这意味着,在方法中对形参的任何修改都不会影响到实参本身。


 2、在方法内部,使用形参来进行计算或操作。


 3、当方法执行完毕并返回时,会将方法返回值压入栈中,同时将栈帧出栈,方法的局部变量表也随之销毁。因此,形参也随之销毁,其存储的值也就被销毁了。


[2.2] 包装类型、String类型:


 首先要明确,包装类型、String类型都是引用类型。


 Java 中的引用类型变量在 JVM 中的存储方式与基本数据类型变量有所不同。引用类型变量存储的是一个指向对象在堆中存储空间的地址,而不是对象本身。因此,引用类型变量的大小是固定的,不受引用对象大小的影响。


 具体来说,引用类型变量在栈中分配一个固定大小的存储空间,用于存储指向堆中对象的地址。当创建一个对象时,JVM 会在堆中分配一段连续的存储空间,用于存储对象的实例变量、类信息等。对象在堆中的存储位置由 JVM 管理,并由引用类型变量记录。


 当引用类型变量被赋值为 null 时,表示该变量不再指向任何对象。如果该引用类型变量没有被使用,那么在垃圾回收器执行垃圾回收时,该对象会被回收,其在堆中占用的存储空间会被释放。


 由于String类和包装类都被设定成不可变的,没有提供value对应的setter方法,而且很多都是final的,我们无法改变其内容,所以其值不变,导致我们看起来好像是值传递(即没有影响原来的值)。





[3] 为什么引用类型传参之后原值可能会变?


 引用传递的是一个引用、这个引用存放的是参数的地址的值,如果在函数中没有改变这个参数的引用地址(没有new一个新的地址—这也叫做浅拷贝),那么就会改变原来的值,影响到传入的参数。(比如数组、集合就是很明显的例子);如果在函数中改变了参数的引用地址,也就是new了一个,那就不会改变参数的值了,这也叫做深拷贝。


 例如:


@Test
public void main() {
     User u1 = new User();
     User u2 = new User();
     changeValue(u1, u2);
     System.out.println(u1+"\n"+u2);
 }
 public void changeValue(User u1,User u2) {
     u1.setUid((long) 1111);
     u2 = new User();
     u2.setUid((long) 1111);
 }
//User(uid=1111, uname=null, uimg=null, utel=null, upwd=null, iden=null, umeto=null, loginIp=null, loginDate=null)
//User(uid=null, uname=null, uimg=null, utel=null, upwd=null, iden=null, umeto=null, loginIp=null, loginDate=null)
相关文章
|
1月前
|
数据可视化 Java
让星星月亮告诉你,通过反射创建类的实例对象,并通过Unsafe theUnsafe来修改实例对象的私有的String类型的成员属性的值
本文介绍了如何使用 Unsafe 类通过反射机制修改对象的私有属性值。主要包括: 1. 获取 Unsafe 的 theUnsafe 属性:通过反射获取 Unsafe类的私有静态属性theUnsafe,并放开其访问权限,以便后续操作 2. 利用反射创建 User 类的实例对象:通过反射创建User类的实例对象,并定义预期值 3. 利用反射获取实例对象的name属性并修改:通过反射获取 User类实例对象的私有属性name,使用 Unsafe`的compareAndSwapObject方法直接在内存地址上修改属性值 核心代码展示了详细的步骤和逻辑,确保了对私有属性的修改不受 JVM 访问权限的限制
50 4
|
1月前
|
存储 分布式计算 NoSQL
大数据-40 Redis 类型集合 string list set sorted hash 指令列表 执行结果 附截图
大数据-40 Redis 类型集合 string list set sorted hash 指令列表 执行结果 附截图
25 3
|
3月前
|
SQL 分布式计算 DataWorks
DataWorks产品使用合集之如何将STRING类型转换为DATETIME类型
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
3月前
|
存储 NoSQL 索引
MPP架构数据仓库使用问题之在ORC文件中,String类型字段是怎么进行编码的
MPP架构数据仓库使用问题之在ORC文件中,String类型字段是怎么进行编码的
|
3月前
|
开发工具 数据安全/隐私保护
【Azure Developer】使用MSAL4J 与 ADAL4J 的SDK时候,遇见了类型冲突问题 "java.util.Collections$SingletonList cannot be cast to java.lang.String"
【Azure Developer】使用MSAL4J 与 ADAL4J 的SDK时候,遇见了类型冲突问题 "java.util.Collections$SingletonList cannot be cast to java.lang.String"
|
3月前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
40 0
|
4月前
|
存储 SQL 分布式计算
MaxCompute产品使用合集之表中的某个列设置为string类型,并且超过了8M,该如何处理
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
4月前
|
存储 NoSQL Redis
Redis07命令-String类型字符串,不管是哪种格式,底层都是字节数组形式存储的,最大空间不超过512m,SET添加,MSET批量添加,INCRBY age 2可以,MSET,INCRSETEX
Redis07命令-String类型字符串,不管是哪种格式,底层都是字节数组形式存储的,最大空间不超过512m,SET添加,MSET批量添加,INCRBY age 2可以,MSET,INCRSETEX
TS定义布尔值,let flag:boolean = true,定义数字类型 let a1:number = 10,赋值 let str1:string = ‘‘,打印c~.log($(str1))
TS定义布尔值,let flag:boolean = true,定义数字类型 let a1:number = 10,赋值 let str1:string = ‘‘,打印c~.log($(str1))
TS,数据类型概述,常见的基本数据类型有number/string/boolean/undefined/null,字符串用““,let food: string = ‘糖葫芦‘,布尔类型
TS,数据类型概述,常见的基本数据类型有number/string/boolean/undefined/null,字符串用““,let food: string = ‘糖葫芦‘,布尔类型

热门文章

最新文章