今天复习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类型的引用传递问题的更多相关文章

  1. JAVA不可变类与可变类、值传递与引用传递深入理解

    一个由try...catch...finally引出的思考,在前面已经初步了解过不可变与可变.值传递与引用传递,在这里再次深入理解. 1.先看下面一个try..catch..finally的例子: P ...

  2. String 的不可变真的是因为 final 吗?

    尽人事,听天命.博主东南大学硕士在读,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 「CS-Wiki」Gitee ...

  3. String 与不可变对象

    什么是不可变对象 ?不可变对象指的是在创建一个对象之后 ,不能再改变它的状态 ,那么这个对象就是不可变的 .不能改变状态的意思是 ,不能改变对象内的成员变量 ,包括基本数据类型的值不能改变 ,引用类型 ...

  4. 关于java是值传递还是引用传递

    一.概念 实际上对这两种传递方式,知乎上有个回答说得很好: 值传递和引用传递,属于函数调用时参数的求值策略(Evaluation Strategy),这是对调用函数时,求值和传值的方式的描述,而非传递 ...

  5. java是值传递还是引用传递

    首先写一个简便的Employee,以便测试使用. class Employee { private String name; public Employee(String name) { this.n ...

  6. java 引用传递和值传递

    1.为什么要分值传递和引用传递: 基本类型存在在栈中,复合类型(对象)存在堆中.操作栈的速度要快于堆,且对象的复制相比基本类型不仅浪费内存而且速度比较慢. 从这里就可以看出来:对象是按照引用传递(数据 ...

  7. java引用传递和值传递

    关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习 ...

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

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

  9. C#中的引用传递、值传递

      先来说下C#中的数据类型.分值类型和引用类型两大类. 值类型:直接存储数据的值,保存在内存中 引用类型:存储对值的引用,实际上存储的就是一个内存的地址 C#预定义的简单类型,像int,float, ...

随机推荐

  1. [UE4]小地图UI放在哪里创建合适?

    在常见的FPS游戏中,玩家死亡以后,还是可以进行聊天和漫游的,因此聊天UI和小地图都应该放在PlayerState中创建

  2. [UE4]Replications,复制

    关于进程 1.进程:运行中的程序 虚幻4游戏进程的四种网络模式 1.StandAlone:单机模式,不联网 2.Client,网络游戏中的客户端. 3.ListenServer,服务器和一个客户端 4 ...

  3. https证书的验证过程与生成方法

    1.简洁的解释: 1.服务器 用RSA生成公钥和私钥2.把公钥放在证书里发送给客户端,私钥自己保存3.客户端首先向一个权威的服务器检查证书的合法性,如果证书合法,客户端产生一段随机数,这个随机数就作为 ...

  4. Go语言 函数,工程管理

    Go语言 函数,工程管理 1.无参无返回值函数的使用 package main import "fmt" func main() { // 无参无返回值函数的调用:函数名() fu ...

  5. U3d学习001-RollBox例子

    1.世界坐标系和局部坐标系(参照物坐标系)——以参照物为父物体节点  2.刚体组件:       获得GetComponent<Rigidbody>();     移动AddForce(n ...

  6. struts2的result的类型配置简介

    一.在strut2的action处理完成后,就应该向用户返回结果信息result 根据以下代码作为实例分析: <package name="Hello" extends=&q ...

  7. 封装MemoryCache

    一.定义一个缓存接口IChace using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

  8. tips:Java中的switch的选择因子

    tips:Java中的switch的选择因子! /*  switch(){   }  */ switch的()中的判断条件能是什么类型呢? 事实上,在我们学习c++的了解中,switch的参数是一个能 ...

  9. IntelliJ IDEA 注释模板设置

    1.idea类注释 打开:file->setting->Editor->Filr and Code Templates->Includes->File Header 类注 ...

  10. LabelFunction 允许在显示数据以前进行处理

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...