原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11683720.html

  一直对String不可变感到疑问, 不知为何说String是不可变的, 有人说final, 有人说其字符串不可改变, 但是我始终不能理解字符串不能改变的真正含义, 遂自行琢磨了一番, 也有了自己的一番见解, 希望记录下来, 日后有新的见解可以随时修改和比较.

  首先final保证String是不可变类(无法被继承,无法被子类修改破坏其内部状态), String的属性也都是final变量, 所以其属性也是不可被破坏的, 属性状态也无法被改变!

  然后是String的内部方法处理方式, 对String的操作方法最终都会返回一个新的String对象, 这就直接导致了返回的是一个新的内存地址引用, 而不是将原内存地址引用的那块内存的值进行修改!(这里就是不可变性重要的地方)

  只用文字难免有些枯燥和不好理解, 用代码说明一下. 用方法和形参的方式更清晰的说明一下同样的情况普通对象和String对象不同!

/**
* 形参变化测试类
*/
public class happyTwo {
public static void main(String[] args) {
User user = new User();
user.name = "zhangsan";
System.out.println(user.name);
tryChangeObj(user);
System.out.println(user.name);
String str = "this is str";
System.out.println(str);
tryChangeStr(str);
System.out.println(str);
} static class User{
public String name;
} public static void tryChangeStr(String formStr){
formStr = "hi, this is formStr";
} public static void tryChangeObj(User formUser){
formUser.name = "lisi";
}
}

  打印信息如下:

   来仔细分析一下:

  1. 对象user, name属性的值刚开始是zhangsan, 因为Java是值传递的, 所以formUser得到了user的内存地址引用值, 此时, formUser直接指向user指向的那块内存, formUser修改了该内存的值, user的内容当然也会变化, 相当于他们其实都是该内存的一个快捷方式.

  2. 为什么String不会变化呢? 难道formStr拿到的不是str的内存地址引用的值吗?

    formStr拿到的当然也是str的内存地址引用的值, 也就是说在

public static void tryChangeStr(String formStr) 这一行当中, formStr和str指向的内存是一样的! 

    变化发生在下面这一行

formStr = "hi, this is formStr";

    刚刚我们说了, String的所有修改操作都会直接返回一个新的String, 这一行给formStr赋新的字符串了, 此时formStr指向的内存地址就变成了该字符串的内存地址了, 所以此时formStr和str当然不是同一个对象了, 它两的值肯定也不会再相同了!

  以上就是我的个人理解, 我理解的不可变是最开始初始化String对象后存储String对象的那块内存中的值不可变, 而不是String对象的引用地址不能改变, 如果理解有误, 希望后期自己可以发现并纠正.

  

关于String不可变的一些理解的更多相关文章

  1. 【翻译】为什么Java中的String不可变

    笔主前言: 众所周知,String是Java的JDK中最重要的基础类之一,在笔主心中的地位已经等同于int.boolean等基础数据类型,是超越了一般Object引用类型的高端大气上档次的存在. 但是 ...

  2. [BS-18] 对OC中不可变类的理解

    对OC中不可变类的理解 OC中存在很多不可变的类(如NSString,NSAttributedString,NSArray,NSDictionary,NSSet等),用它们创建的对象存在于堆内存中,但 ...

  3. java String 不可变

    关于String不可变的问题也看了很多,最近看了一篇讲的非常好的文章,总结如下 所谓的不可变,并非真的不可变String s = "123"; s = "456" ...

  4. java基础-String不可变的好处

    一.java内部String类的实现: java 8: public final class String implements java.io.Serializable, Comparable< ...

  5. 类加载, 静态变量初始化, String不可变, 泛型使用, 内部类

    1.java变量类型 java变量类型分:基本数据类型变量和Object数据类型变量,变量也是占用者内存的 例如: int i = 3; i这个变量保存的就是整形3, 占32位 Object a = ...

  6. String字符串为什么不可变的深入理解

    String是被final修饰的,是不可变对象,那么这句什么意思呢.在学习scala时候var,val时候,就想到这个问题,所以记录下 看案例: package com.cxy; import sun ...

  7. Java 基础 - 如何理解String不可变

    ref: https://www.zhihu.com/question/20618891 第一个答案. 扩展“ Java 基础 - System.arraycopy() 浅拷贝 深拷贝

  8. java String不可变对象,但StringBuffer是可变对象

    什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的.不 ...

  9. String不可变StringBuffer可变

    String是一个类,也可以表示字符串数据类型 String:是对象不是原始类型.为不可变对象,一旦被创建,就不能修改它的值.对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值 ...

随机推荐

  1. linux(CentOS7) 之 ntp时间同步配置步骤

    下 载 百度搜索 ntp rpm 下载(或直接进入官网https://pkgs.org/download/ntp) 搜多ntp,选择centos7 64位下载,ntpdata 是依赖包也要下载 基 础 ...

  2. win10 安装vue 详解-包括node.js、npm、webpack

    1.下载 去官网下载 node.js https://nodejs.org/en/download/ 一般不会选择最新的,我安装的是 12.18.4 进入历史记录页面网址 https://nodejs ...

  3. Shell 中的 expect 命令

    目录 expect 介绍 expect 安装 expect 语法 自动拷贝文件到远程主机 示例一 示例二 示例三 示例四 expect 介绍 借助 expect 处理交互的命令,可以将交互过程如 ss ...

  4. android 解决报错 installation failed with message Failed to finalize session : INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION: Failed parse during installPackageLI: Failed to read manifest from /xx/xx/xx.apk

    新工程启动报错 怎么办? 解决: 将这个选项去掉勾选后点击ok即可

  5. centos7 单用户模式修改root密码

    1. 在虚拟机重启客户机后.会出现下面进入界面.按e键 2.按了e键后,会出现下面的界面.此时按↓键.找到linux16 3.将光标移动到UTF-8后面,添加init=/bin/sh,并按 ctrl  ...

  6. SYCOJ2100摆动序列

    题目-摆动序列 (shiyancang.cn) 直接分成两部分,插入即可.只有一个地方不对,那就是符号.两个大的放一个小的,两个小的放一个大的.那么每次的大的放最大的,每次的小的放其次小的,用完就不用 ...

  7. 一键AI着色,黑白老照片画面瞬间鲜活

    很多老照片或者电影受时代技术所限制,只能以黑白形式保存:经过编辑后的黑白视频和图片早已丢失彩色原图,这对于保存者来说都十分遗憾.如何能将单一乏味.陈旧斑驳的黑白照片变成鲜活亮丽的彩色照片,从照片中重新 ...

  8. Java反射详解:入门+使用+原理+应用场景

    反射非常强大和有用,现在市面上绝大部分框架(spring.mybatis.rocketmq等等)中都有反射的影子,反射机制在框架设计中占有举足轻重的作用. 所以,在你Java进阶的道路上,你需要掌握好 ...

  9. Protobuf使用--go和C#

    一.Go安装及使用protobuf工具 以下都是基于Linux系统: 1.安装 A) protobuf 编译工具安装 1.下载 protoBuf: cd $GOPATH/src/ git clone ...

  10. 字节一面:事务还没提交的时候,redolog 能不能被持久化到磁盘呢?

    又是被自己菜醒的一天,总结面经看到这题目听都没听过,打开百度就像吃饭一样自然 老规矩,背诵版在文末.点击阅读原文可以直达我收录整理的各大厂面试真题 首先,咱需要明白的是,啥是持久化? 听起来高大上,换 ...