参数传递

Java 中的参数传递分为 “值传递”“引用传递”

如果你学过 C/C++应该很好理解,就是所谓的 "值传递""指针传递"

值传递

在 Java 中,"值传递" 就是传递真实值的一个副本,其实就是重新生成了一个值,新的值怎么改变并不影响原来的值,举个例子:

public class Test {

	public static void main(String[] args) {
Test t1 = new Test();
int a = 1;
t1.paramTest(1);
System.out.println("main: " + a); } private void intParamTest(int a) {
a++;
System.out.println(a);
} }

输出结果:

2

main: 1

我们可以看到,虽然我们去调用了方法让 a 的值自增 1 ,但是 main 方法中的 a 还是 1

实践出真知:我们可以得出一个结论,基本数据类型是值传递(传递的是值的一个克隆)

引用传递

引用传递 顾名思义传递的是参数的引用,也就是参数的地址,在 Java 中,对象作为参数传递时,传递的就是对象的引用地址

所以当我们对 对象进行操作的时候,实际上我们操作的是真实的对象,原对象也会随之改变,还是来实践出真知:

public class Test {

	public static void main(String[] args) {
Test t1 = new Test();
Person p = new Person("小冯同学",18);
System.out.println("方法调用前:" + p.name);
t1.personTest(p);
System.out.println("方法调用后:" + p.name); } private void personTest(Person p) {
p.name = "张三同学";
} }
class Person{
public String name;
public int age;
public Person(String name,int age) {
this.name = name;
this.age = age;
}
}

输出结果:

方法调用前:小冯同学

方法调用后:张三同学

看到这里,我们可以得出一个结论:对象作为参数的时候,传递的是对象的引用地址。

总结

根据以上两个结论,我们总结一下:

  • 当参数类型是基本数据类型时,传递是的一个拷贝值,拷贝值是生是死不影响原来的值
  • 当参数类型是一个对象时,传递的是对象的引用地址,操作的是同一个对象

分享一个小故事,大概是两年前刚开始接触 SSM框架的时候,当时有一个需求就是:插入一个 user,然后返回插入成功和 user的基本信息(包括 userid),然后我们呢当时数据库的 user表的 id自增的,插入的 user是没有 id的,id是插入后 mysql自增主键生成的,当时借助了 mybatis的主键回添功能,大概长这样子:

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into t_user (u_name,u_age) values (#{name},#{age});
</insert>

然后之前插入的那条 user记录就有 id了,当时年少气盛的我还不懂什么值传递引用传递,当时的表情是这样的



属实是 Java 基础太拉了,哈哈

然后现在发现其实原理就这么简单,插入后把 id 查出来,直接塞到你之前插入的那个 user 对象中 o 了

String

相信大家在面试场上,面试官经常会问你一些关于 String 的问题

然后你发现你之前背的结论不管用了(基本数据类型值传递,对象引用传递

还是实践出真知:

public class Test {

	public static void main(String[] args) {
Test t1 = new Test();
String s = "hello";
t1.append(s);
System.out.println("main: " + s); } private void append(String s) {
s += " world";
System.out.println("method: " + s);
} }

输出结果:

method: hello world

main: hello

很多同学应该也是这个表情



“String 是对象啊,传递的不是地址吗,操作的不是真实的对象吗,为什么没有改变啊”

同学们呼声很大啊

你可以把 String 归类到基本数据类型中去,我这样说大家肯定不会买账,这还要从 String 的关键字 final 说起

大家都知道被 final 修饰的都是常量,常量有什么特点?当然是不能改变啊

所以我们对 String 进行改变的时候,编译器在底层是为我们重新生成了一个 String 对象,来看一道经典面试题:

	public static void main(String[] args) {
String s1 = "a";
String s2 = s1;
s2 = "ab";
String s3 = new String("ab");
String s4 = s3 + "cd";
String s5 = "abcd";
}

请问这段程序一共生成了多少个对象?

有没有猜到 5 个的,正确答案就是 5 个。

池化技术了解过吧?线程池,对象池,人才池...

String 底层用到的就是 常量池

第二行:s1 = "a" ,生成常量 a 放入池中,然后 s1 指定这个常量的地址

第三行:s2 = s1 ,就是生成一个 s2 的变量指向 s1 的地址。

第四行:s2 = "ab",是把 "a" 变成的 "ab" 么?当然不是,人家都是常量了,不能被改变,那怎么办?当然是重新生成一个常量 "ab",放入池中,然后 s2 指向 "ab" 的地址

第五行: s3 = new String("ab"),使用了 new 关键字,所以会生成一个新的常量 "ab",(当然官方也不建议我们这样做,这样就不能复用池中的 "ab" 了)

第六行:池里没有"cd" ,创建 "cd" 扔到池子里,s3 是 "ab" ,用加号连接起来就是 "abcd",池里没有 "abcd",创建 "abcd" 扔到池里

第七行:
s5 = "abcd"
,因为池里有 "abcd",所以直接复用就是,不用重新创建

所以一共生成了 5 个对象,分别是:"a","ab","ab","cd","abcd"

至于 Java 为什么要这样设计,大家感兴趣可以去探究探究

据我所知,Java 里用得最多的数据类型就是 String,如果不停的创建 String 对象,对内存来说应该是一笔很大的开销,使用常量池可以对其进行复用,算是对 String 的优化

可能不太准确,hhh,也欢迎大佬在下面评论

文笔不是很专业,但还是希望你没看一篇博客都能吸收到新的知识,认真沉淀~

浅谈Java-String到底是值传递还是引用传递?的更多相关文章

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

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

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

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

  3. Java调用函数传递参数到底是值传递还是引用传递

    今天翻看微信上有关Java技术的公众号时,看到了一篇关于Java中值传递的问题,文章讨论了在Java中调用函数进行传参的时候到底是值传递还是引用传递这个面试时会问到的问题.之前也接触过类似的问题,但只 ...

  4. Java中到底是值传递还是引用传递?

    Java中到底是值传递还是引用传递? 我们先回顾一下基本概念 实参和形参 参数在编程语言中是执行程序需要的数据,这个数据一般保存在变量中.在Java中定义一个方法时,可以定义一些参数, 举个例子: p ...

  5. 188W+程序员关注过的问题:Java到底是值传递还是引用传递?

    在逛 Stack Overflow 的时候,发现了一些访问量像阿尔卑斯山一样高的问题,比如说这个:Java 到底是值传递还是引用传递?访问量足足有 188万+,这不得了啊!说明有很多很多的程序员被这个 ...

  6. [转帖]Stack Overflow上188万浏览量的提问:Java 到底是值传递还是引用传递?

    Stack Overflow上188万浏览量的提问:Java 到底是值传递还是引用传递? http://www.itpub.net/2019/12/03/4567/   在逛 Stack Overfl ...

  7. JAVA方法中参数到底是值传递还是引用传递

    当一个对象被当作参数传递到一个方法后,在此方法内可以改变这个对象的属性,那么这里到底是值传递还是引用传递? 答:是值传递.Java 语言的参数传递只有值传递.当一个实例对象作为参数被传递到方法中时,参 ...

  8. 【Java思考】Java 中的实参与形参之间的传递到底是值传递还是引用传递呢?

    科普: 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数. 引用传递(pass by reference)是指在 ...

  9. Java 到底是值传递还是引用传递?

    关于这个问题,引发过很多广泛的讨论,看来很多程序员对于这个问题的理解都不尽相同,甚至很多人理解的是错误的.还有的人可能知道Java中的参数传递是值传递,但是说不出来为什么. 在开始深入讲解之前,有必要 ...

  10. 死磕面试系列,Java到底是值传递还是引用传递?

    Java到底是值传递还是引用传递? 这虽然是一个老生常谈的问题,但是对于没有深入研究过这块,或者Java基础不牢的同学,还是很难回答得让人满意. 可能很多同学能够很轻松的背出JVM.分布式事务.高并发 ...

随机推荐

  1. 说出几条 Java 中方法重载的最佳实践?

    下面有几条可以遵循的方法重载的最佳实践来避免造成自动装箱的混乱. a)不要重载这样的方法:一个方法接收 int 参数,而另个方法接收 Integer 参 数. b)不要重载参数数量一致,而只是参数顺序 ...

  2. Java 线程数过多会造成什么异常?

    1.线程的生命周期开销非常高 2.消耗过多的 CPU 资源 如果可运行的线程数量多于可用处理器的数量,那么有线程将会被闲置.大量空 闲的线程会占用许多内存,给垃圾回收器带来压力,而且大量的线程在竞争  ...

  3. 原来 flexbox 是这么工作的

    Flexbox 是一种 CSS 布局机制,可以说是目前浏览器原生支持的最好.使用最广泛的布局机制了.本文通过一些例子来说明 Flexbox 布局的工作原理,可以让我们更好的使用 Flexbox. 与 ...

  4. 基于HTML5的网络拓扑图(1)

    什么是网络拓扑 网络拓扑,指构成网络的成员间特定的排列方式.分为物理的,即真实的.或者逻辑的,即虚拟的两种.如果两个网络的连接结构相同,我们就説它们的网络拓扑相同,尽管它们各自内部的物理接线.节点间距 ...

  5. SQL语句中关于日期的操作(非常的有用)

    在SQL Server 里的日期数据,我们经常可以用 字段<='2008-5-20'这样的表达式,但在oracle却不可以,因为数据类型不一样 字段是date型,'2008-5-20'是字符型, ...

  6. Android控件设置半透明+EditText设置默认值+ 控件居中

    Android控件设置半透明 效果 代码: android:background="#50FFFFFF" 50表示50%透明 Android:EditText设置默认值 andro ...

  7. Cannot get a STRING value from a NUMERIC cell poi异常解决

    ref:http://www.tpyyes.com/a/kuozhan/2017/0902/199.html poi导入excel表格数据时报java.lang.IllegalStateExcepti ...

  8. Blazor组件自做五 : 使用JS隔离封装Google地图

    Blazor组件自做五: 使用JS隔离封装Google地图 运行截图 演示地址 正式开始 1. 谷歌地图API 谷歌开发文档 开始学习 Maps JavaScript API 的最简单方法是查看一个简 ...

  9. 数据库篇:mysql事务原理之MVCC视图+锁

    前言 数据库的事务特性 数据并发读写时遇到的一致性问题 mysql事务的隔离级别 MVCC的实现原理 锁和隔离级别 关注公众号,一起交流,微信搜一搜: 潜行前行 1 数据库的事务特性 原子性:同一个事 ...

  10. typora简单使用手册

    typora简单使用手册讲解`` 下载网站 网址:https://typoraio.cn/ 苹果电脑:https://typora.en.softonic.com/ 正版呢当然是收费 破解版自行百度 ...