String类为啥是final的?

我们找到string的jdk源码

1.看到String类被final修饰。这里你就要说出被final修饰的类不能被继承,方法不能被重写,变量不能被修改。

2.看到final修饰的char[]代表了被存储的数据不可更改性。但是:虽然final代表了不可变,但仅仅是引用地址不可变,并不代表了数组本身不会变,请看下面图片

上图说明:数组中的值发生了改变。

上图说明:无论如何修改,数组的地址值不会改变。

综上:所以在这里只有final修饰是不能确保string的不可变性。还需要privite修饰。才能确保不可变性。

  • 因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。
  • 因为字符串是不可变的,所以在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。

除了 String 类,系统类库中还提供了一些其他的不可变类,基本类型的包装类、BigInteger、BigDecimal等等。这些不可变类比可变类更加易于设计、实现和使用,不容易出错且更加安全。另外,要记住并不仅仅是靠一个 final 关键字来实现不可变的,更多的是靠类内部的具体实现细节。


String真的不可变吗?

 
综上所述,String 的确是个不可变类,但是真的没有办法改变 String 对象的值吗?答案肯定是否定的,反射机制可以做到很多平常做不到的事情。
String str = "123";
System.out.println(str);
Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
char[] value = (char[]) field.get(str);
value[1] = '3'; 执行结果:
123
133
很显然,通过反射可以破坏 String 的不可变性。

参考:https://blog.csdn.net/weixin_44946052/article/details/89409188

https://www.jianshu.com/p/9c7f5daac283

https://segmentfault.com/a/1190000009914328

String类为什么是不可变的的更多相关文章

  1. Java技术——String类为什么是不可变的

    0. 前言   如果一个对象,在它创建完成之后不能再改变它的状态,包括对象内的成员变量.基本数据类型的值等等.那么这个对象就是不可变的.众所周知String类就是不可变的.转载请注明出处为SEU_Ca ...

  2. 反射消除String类对象的不可变特性

    大家都知道,在JAVA中字符串一旦声明就不可改变,如果尝试修改字符串的内容,将会重新实例化一个新的字符串对象,这也是为了安全性和效率. 由于字符串在程序之中被大量使用,所以JAVA引入了一个字符串常量 ...

  3. Java的string类为什么是不可变的

    最流行的Java面试题之一就是:什么是不可变对象(immutable object),不可变对象有什么好处,在什么情况下应该用,或者更具体一些,Java的String类为什么要设成immutable类 ...

  4. 为什么Java中的String类是不可变的?

    String类是Java中的一个不可变类(immutable class). 简单来说,不可变类就是实例在被创建之后不可修改. 在<Effective Java> Item 15 中提到了 ...

  5. 为什么String类是不可变的?

    为什么String类是不可变的? String类 什么是不可变对象 当满足以下条件时,对象才是不可变的: 对象创建以后其状态就不能修改. 对象的所有域都是final类型的. 对象是正确创建的(在对象的 ...

  6. String类和StringBuffer类的区别

    首先,String和StringBuffer主要有2个区别: (1)String类对象为不可变对象,一旦你修改了String对象的值,隐性重新创建了一个新的对象,释放原String对象,StringB ...

  7. String 类相关知识

    1.常用方法 1)判断字符串是否为空 public boolean isEmpty()2)获取字符串长度 public int length()3)截取子子串 public String substr ...

  8. 【Java 进阶篇】【第一课】String类

    引用 String类包含在java.lang包中.这个包会在Java启动的时候自动import,所以可以当做一个内置类(built-in class).我们不需要显式的使用import引入String ...

  9. IT第九天 - 包、访问修饰符、变量的内存分配、String类中常用方法

    IT第九天 上午 包 1.包的命名规则:域名.项目名称.模块名 2.如:Wfei.com.windows.login 访问限制符 1.四种访问限制符分别对应为: (1)default:默认的,默认为p ...

随机推荐

  1. SqlDataReader阅读器关闭时尝试调用 HasRows 无效

    SqlDataReader阅读器关闭时尝试调用 HasRows 无效 原创长白山上放羊娃 发布于2018-07-25 00:29:27 阅读数 538  收藏 展开 在SqlHelper中封装好的Sq ...

  2. 003 CSS汇总

    字体属性:(font) 大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX.PD 样式 {font-style: obl ...

  3. python操作oracle完整教程

    1.    连接对象 操作数据库之前,首先要建立数据库连接.有下面几个方法进行连接. >>>import cx_Oracle>>>db = cx_Oracle.co ...

  4. 解密国内BAT等大厂前端技术体系-美团点评之下篇(长文建议收藏)

    引言 在上篇中,我已经介绍了美团点评的业务情况.大前端的技术体系,其中大前端的技术全景图如下: 上篇重点介绍了工程化和代码质量的部分,工程化涵盖了客户端持续集成平台-MCI.全端监控平台-CAT.移动 ...

  5. php 发送手机验证码

    嗯哼,做为一个好的程序猿,一定要给顾客爸爸剁手的时候,充分的告诉他,你剁完手了,所以不只有邮件通知还要有手机短信的通知,今天就来写一下php发送验证码 1.首先我就写了几个个方法,因为配置在后台,直接 ...

  6. springboot @Configuration @bean注解作用

    @Configuration注解可以达到在Spring中使用xml配置文件的作用 @Bean就等同于xml配置文件中的<bean> 在spring项目中我们集成第三方的框架如shiro会在 ...

  7. 【Struts 动态表单】DynaActionForm

    RegisterAction package k.action; import org.apache.struts.action.ActionForm; import org.apache.strut ...

  8. SpringCloud全家桶学习之Feign负载均衡----Feign(四)

    一.Feign概述 (1)Feign是什么? 官网地址:https://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-f ...

  9. 创建jsp文件时报错,"javax.servlet.http.HttpServlet" was not found on the Java)

    原因: 创建jsp文件的步骤如下: 出现"javax.servlet.http.HttpServlet" was not found on the Java) 报错信息就是因为没有 ...

  10. JS-正则表达式常规运用

    限制文本框只能输入0和正数 <input type="text" onkeyup="this.value=this.value.replace(/\D/g,'')& ...