对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, ...
随机推荐
- 6行代码解决golang TCP粘包
转自:https://studygolang.com/articles/12483 什么是TCP粘包问题以及为什么会产生TCP粘包,本文不加讨论.本文使用golang的bufio.Scanner来实现 ...
- Win7删除缓存垃圾文件
del /s /f /q C:\*.tmp
- sql server 日志传送问题整理
1.数据库备用/只读状态恢复为联机 SELECT DATABASEPROPERTYEX('ty_szum_oa_v2_bak','IsInStandBy') restore database ty_s ...
- javascript-typeof篇
isString (o) { //是否字符串 return Object.prototype.toString.call(o).slice(8, -1) === 'String' } isNumber ...
- MySql存储过程与函数详解
存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程和函数可以避免开发人员重复的编写相同的SQL语句.而且,存储过程和函数是在MyS ...
- Java - 30 Java 网络编程
Java 网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net包中J2SE的API包含有类和接口,它们提供低层次的通信细节.你可以直接使用这些类和接 ...
- CS229 6.6 Neurons Networks PCA主成分分析
主成分分析(PCA)是一种经典的降维算法,基于基变换,数据原来位于标准坐标基下,将其投影到前k个最大特征值对应的特征向量所组成的基上,使得数据在新基各个维度有最大的方差,且在新基的各个维度上数据是不相 ...
- ERROR: duplicate key value violates unique constraint "xxx"
在postgresql中,由于为表的主键建立了自增序列,且数据是从正式库拷贝到正式库的,所以报错如下: (主要原因:自增序列中的当前序列号小于真实数据中的最大主键值,因此在新增数据时,会报唯一值的错误 ...
- phpmyadmin无登录表单无法登陆
发现我的博客的phpmyadmin登录过一次成功之后,后面在登录没有登录表单了,查了很多原因,下面的方法亲测可以解决 打开 phpMyAdmin\libraries\plugins\auth\Auth ...
- BZOJ2321 [BeiJing2011集训] 星器
2321: [BeiJing2011集训]星器 Time Limit: 1 Sec Memory Limit: 128 MB Description Magic Land上的时间又过了若干世纪…… ...