对String值不可变的理解以及String类型的引用传递问题
今天复习java时,突然注意到了一句以前没有注意过的一句话,String 是final修饰的,其值是不可变的。当时看的一脸懵逼,String str = "abc"; str = "abcde"这两行代码没有任何的错误的。上网百度了许久,还是整理下来防止以后忘记吧。
首先要理解的是,string说的不可变是其值不可变,比如String str = "abc",不可变值得是abc不可变,当我们str = “abcde”时,abc没有被销毁,仍然存放在常量池中,只不过是让str指向了“abcde”的内存地址。所以就算不停的赋值,改变的也只是str引用的地址问题,右边的值是不改变的。就举个String类型的引用传递来详细说明下吧
public class Test { public static String appStr(String a){
a += "bbb";
return a;
} public static StringBuilder appSb(StringBuilder sb){
sb.append("bbb");
return sb;
} public static void main(String[] args) {
String s = "aaa";
String s2 = Test.appStr(s);
//注意这边打印的是s,不是s2
System.out.println(s); StringBuilder sb = new StringBuilder("aaa");
StringBuilder sb2 = Test.appSb(sb);
//注意这边打印的是sb,不是sb2
System.out.println(sb.toString());
}
}
上输代码的输出结果是
aaa
aaabbb
下面来分析一下当运行到Test.appStr(s)时,将s(实参)的地址传递给a(形参),此时a="aaa",a+="bbb"之后,a="aaabbb",但是由于string是不可变的,所以在内存上就会重新分配一片内存空间给aaabbb,然后a指向该地址;而s的指向地址却没有发生改变,所以s的值打印出来仍然是aaa;
同理分析StringBuilder,也是引用类型,传递的是地址值,当形参sb传递给实参sb之后,方法对sb进行了修改,sb的值发生了改变(并不像string一样值不可变,重新分配空间),所以运行之后sb的指向值就发生了改变,随后打印的就是aaabbb了。
这样应该就可以理解String的不可变了。
对象一直存在且没有变化,只是指向发生了变换
对String值不可变的理解以及String类型的引用传递问题的更多相关文章
- JAVA不可变类与可变类、值传递与引用传递深入理解
一个由try...catch...finally引出的思考,在前面已经初步了解过不可变与可变.值传递与引用传递,在这里再次深入理解. 1.先看下面一个try..catch..finally的例子: P ...
- String 的不可变真的是因为 final 吗?
尽人事,听天命.博主东南大学硕士在读,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 「CS-Wiki」Gitee ...
- String 与不可变对象
什么是不可变对象 ?不可变对象指的是在创建一个对象之后 ,不能再改变它的状态 ,那么这个对象就是不可变的 .不能改变状态的意思是 ,不能改变对象内的成员变量 ,包括基本数据类型的值不能改变 ,引用类型 ...
- 关于java是值传递还是引用传递
一.概念 实际上对这两种传递方式,知乎上有个回答说得很好: 值传递和引用传递,属于函数调用时参数的求值策略(Evaluation Strategy),这是对调用函数时,求值和传值的方式的描述,而非传递 ...
- java是值传递还是引用传递
首先写一个简便的Employee,以便测试使用. class Employee { private String name; public Employee(String name) { this.n ...
- java 引用传递和值传递
1.为什么要分值传递和引用传递: 基本类型存在在栈中,复合类型(对象)存在堆中.操作栈的速度要快于堆,且对象的复制相比基本类型不仅浪费内存而且速度比较慢. 从这里就可以看出来:对象是按照引用传递(数据 ...
- java引用传递和值传递
关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习 ...
- Java 到底是值传递还是引用传递?
关于这个问题,引发过很多广泛的讨论,看来很多程序员对于这个问题的理解都不尽相同,甚至很多人理解的是错误的.还有的人可能知道Java中的参数传递是值传递,但是说不出来为什么. 在开始深入讲解之前,有必要 ...
- C#中的引用传递、值传递
先来说下C#中的数据类型.分值类型和引用类型两大类. 值类型:直接存储数据的值,保存在内存中 引用类型:存储对值的引用,实际上存储的就是一个内存的地址 C#预定义的简单类型,像int,float, ...
随机推荐
- Jmeter(四十一)分布式测试(转!)
寄语路人休掩鼻,活人不及死人香. -------<随园诗话>袁枚 转自:https://www.cnblogs.com/imyalost/p/8306866.html 1.修改Contor ...
- JIT和AOT编译详解
JIT和AOT编译介绍 JIT - Just-In-Time 实时编译,即时编译 通常所说的JIT的优势是Profile-Based Optimization,也就是边跑边优化 ...
- 2018/11/5 每日分析-test
郑醇1901,M30向上一笔中,只是看起来不太值得做,主要因为现在30分钟向上一笔空间无法判定,未必能上去(M5中枢如果向上突破并且不背驰才可能有机会:如果直接下去或者向上后背驰,那么这里就只是一个M ...
- [深度分析] Python Web 开发框架 Bottle
[深度分析] Python Web 开发框架 Bottle(这个真的他妈的经典!!!) 作者:lhf2009913 Bottle 是一个非常精致的WSGI框架,它提供了 Python Web开发中需要 ...
- 第11章 拾遗4:IPv6(2)_给计算机配置IPv6地址
4. 给计算机配置IPv6地址 4.1 无状态自动配置IPv6地址 (1)网络拓扑 ①无状态地址自动配置是指不需要DHCP服务器进行管理,由客户端向路由器发送前缀请求(RS)询问其所在网段.路由器收到 ...
- C#语言,求成绩平均数。
输入大于五的人数成绩,去掉两个最高分,和两个最低分,求其平均数. Console.Write("请输入人数"); int renshu = int.Parse(Console.Re ...
- mac gcc develop
1:check version gcc -v / g++ -v 2:compile gcc *.c / g++ *.cpp outfile: a.out 3:excute ./a.out ...
- python序列化模块
什么叫序列化——将原本的字典.列表等内容转换成一个字符串的过程就叫做序列化. 序列化的目的 1.以某种存储形式使自定义对象持久化: 2.将对象从一个地方传递到另一个地方. 3.使程序更具维护性. ...
- 安全测试6_Web安全工具第三节(Web安全工具)
之前学习了下安全工具前的一些基础知识,今天来学习下安全工具,这些工具是python写的. 1.敏感文件探测入门: 敏感文件探测的原理如下: 一般探测敏感文件我们都是借助工具扫描,这里我给大家推荐一个简 ...
- 报错500 DEFAULT_INCOMPATIBLE_IMPROVEMENTS
freemarker整合springMVC报错如下:org.springframework.beans.factory.BeanCreationException: Error creating be ...