原创:转载需注明原创地址 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. 编写Java程序,创建一个 Person 类,该类中有一个类成员变量 country、一个实例变量 name 和另一个实例变量 age。

    返回本章节 返回作业目录 需求说明: 创建一个 Person 类,该类中有一个类成员变量 country.一个实例变量 name 和另一个实例变量 age. country 表示地区,name 表示姓 ...

  2. Notepad++快速选中多行

    我们在编辑文章的时候, 通常需要选择多行连续的文本, 可以使用Shift+鼠标选择多行文本, 如果一次需要选择的文本太多, 比如选择10000到20000行之间的文本, 鼠标要拉好久,手一累一抖,又要 ...

  3. Spring @Bean 注解的使用

    使用说明 这个注解主要用在方法上,声明当前方法体中包含了最终产生 bean 实例的逻辑,方法的返回值是一个 Bean.这个 bean 会被 Spring 加入到容器中进行管理,默认情况下 bean 的 ...

  4. ES6嵌套对象的解构

    有下列对象需要解构: const obj:any[] = [ { id: 33, username: "mengsongna", realName: "孟松娜" ...

  5. [ Flask ] myblog_flask问题集(RESTfull风格)

    VUE问题 前端VUE怎么捕获所有404NOT FOUND的路由呢? [ 解决方案 ] vue-router路由守卫,参考文档:动态路由匹配 对于路由.../edit/<id>,自己能编辑 ...

  6. [转]浮点运算decimal.js

    开发过程中免不了有浮点运算,JavaScript浮点运算的精度问题会带来一些困扰 JavaScript 只有一种数字类型 ( Number ) JavaScript采用 IEEE 754 标准双精度浮 ...

  7. 灵雀云新一期DevOps认证培训圆满结束,下期学员招募同步开启

    近日,灵雀云最新一期EXIN DevOps认证培训在北京圆满结束,来自某知名运营商领域ISV的近40名学员以百分百的通过率为此次培训画上圆满的句号. 灵雀云是国内首家在DevOps培训领域与EXIN合 ...

  8. hisql orm update表数据更新文档

    更新 HiSql数据更新 HiSql 提供了好几种数据更新的方式下面一一介绍一下 如果你的表中增加了这四个字段 字段 描述 类型 CreateTime 创建时间 DateTime CreateName ...

  9. JUC之线程池基础

    线程池 定义和方法 线程池的工作时控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等待其他线程执行完成,再从队列中取出任 ...

  10. 《剑指offer》面试题06. 从尾到头打印链表

    问题描述 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 10 ...