String真的不可变吗?

Java中的String是不可变对象

在面向对象及函数编程语言中,不可变对象(英语:Immutable object)是一种对象,在被创造之后,它的状态就不可以被改变。至于状态可以被改变的对象,则被称为可变对象(英语:mutable object)。-- 来自百度百科

Java8 String源码

 

arduino

代码解读

复制代码

public final class String    implements java.io.Serializable, Comparable<String>, CharSequence {    /** The value is used for character storage. */    private final char value[];//Java 9已经优化为byte数组了 ​    /** Cache the hash code for the string */    private int hash; // Default to 0       ... }

显然String字符串内部是使用char[]数组来存储。

而这个char[]数组是用 private final来修饰的,private就体现着面向对象的封装特性,并且String没有提供供外部访问的方法,这就意味着这个属性无法被外部访问;final则意味着这个属性无法修改,无法重新指向其他对象。且String 类没有提供/暴露修改这个字符串的方法。

因此,String是不可变对象

不可变的优点

  • 线程安全。同一个字符串实例可以被多个线程共享,因为字符串不可变,本身就是线程安全的。
  • 支持hash映射。因为String的hash值经常会使用到,比如作为 Map 的键,不可变的特性也就使得hash值不会变,不需要重新计算。
  • 字符串常量池优化。String对象创建之后,会缓存到字符串常量池中,下次需要创建同样的对象时,可以直接返回缓存的引用。

一定不可变吗

事实上,可以通过反射来改变String中的值

 

rust

代码解读

复制代码

String str = "abcdef"; System.out.println("修改前的地址值:" + str + ",hash值"+ str.hashCode()); Class<? extends String> aClass = str.getClass(); Field value = aClass.getDeclaredField("value"); value.setAccessible(true); value.set(str,"seven".getBytes()); System.out.println("修改后的地址值:" + str + ",hash值"+ str.hashCode());

显然修改后的还是同一个地址和hash值

整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记的【点击此处即可】即可免费获取

bash

代码解读

复制代码

修改前的地址值:abcdef,hash值-1424385949 修改后的地址值:seven,hash值-1424385949

查看源码可以看到,计算hashcode后hash值是由一个常量缓存下来的,所以通过反射修改后hashCode并不会变,除非进行重新计算。

注意:用反射修改String的值破坏了String的immutable特征,可能会带来各种问题,以上只是提供一个思路,不建议这么做。

不可变类都建议参考String类一样,写个变量缓存hashcode,从而防止高并发下的计算

 

ini

代码解读

复制代码

public int hashCode() {    int h = hash;    if (h == 0 && !hashIsZero) {        h = isLatin1() ? StringLatin1.hashCode(value)                       : StringUTF16.hashCode(value);        if (h == 0) {            hashIsZero = true;       } else {            hash = h;       }   }    return h; }

关于作者

来自一线程序员Seven的探索与实践,持续学习迭代中~

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值