一文带你深入了解Java String的不可变性
String 类
String 类结构
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { // ... }
Java String 类是 java.lang 包中的类,其实现了 java.io.Serializable, Comparable, CharSequence 等接口。
String 类对象中存储的字符串,最终都是以字符形式存储在其 char[] 数组中,获取时从数组中读取字符列表,且 String 中该属性使用了 final 关键字定义。
private final char value[];
除此之外,String 类在 Object 的基础上重写了 equals() 和 hashCode() 方法,
- equals() 除了使用 == 判断相等外,还会遍历循环比较两个字符串对应字符串数组中的每个字符,如果完全相同也会认为字符串相等。
- toString() 方法直接返回字符串本身,因为其就是字符串,无需 toString 转换
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
String 的不可变性怎么理解
Java 中 String 类是不可变的,这意味着一旦创建了一个 String 对象,就不能再修改它的值。
String str = "abc"; str = "123"; System.out.println(str); // 输出 123
- 上述代码看似是改变了字符串内容,但是实际上只是将变量 str 指向的地址由 "abc" 改成了 "123",在字符串常量池中 "abc" 仍然存在,不被改变。
- 对于 String 提供的 trim()、replace() 等修改字符串字面值的方法也是同理,都是重新创建一个字符串返回,并没有修改原始字符串。
String 类的不可变性体现在如下方面:
1.String 类使用 final 修饰,保证该类不会被继承进行修改
2.String 类中存储内容的 char [] 使用 final 修饰,保证字符数组引用不会被修改
3.尽管 String 类的 char[] 中的元素仍可以修改,但是又通过如下两种方式控制不被修改
- char[] 定义为 private ,即不可以从外部进行操作
- String 类中所有内部方法都避免操作 char[] 内容
基于上述内容,保证了 String 的 char[] 内容是不可变的,即 String 的不可变性。
由于 String 类是不可变的,所以它的性能比较高,且是线程安全的,即多个线程可以同时访问同一个 String 对象,而不会出现线程问题。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; //... }
String 类的常用方法都有那些
- length():返回字符串长度
- trim():去除字符串两端空白。
- toLowerCase():将字符串转成小写字母。
- toUpperCase():将字符串转成大写字符。
- charAt(int index):返回指定索引处的字符。
- inexOf(char c):返回指定字符的索引。
- replace():字符串替换。
- split():分割字符串,返回一个分割后的字符串数组。
- substring (int beginIndex, int endIndex):返回从 beginIndex 到 endIndex-1 的子字符串。
- equals(Object obj):字符串比较是否相等。
- getBytes():返回字符串的 byte 类型数组。
String 常用工具类
StringUtils 是处理字符串的工具类,String 类实现 CharSequence 接口,为实现不同的 String 操作,各大厂商封装了相应的 StringUtils 工具类。
org.springframework.util.StringUtils
,spring 自带 String 工具类,可以满足基本的使用。
Java Web 中不需要导包,在 spring-core 包中存在,可以直接使用
org.apache.commons.lang.StringUtils
, apache 提供的 String 工具类,对 java.lang 的扩展。
lang 最新版本是 2.6,最低要求 Java1.2 以上,目前官方已不再维护。
apache-commons-lang3.StringUtils
,lang 的升级包,将参数换成 CharSequence 数组,贴合 String 类型的内部结构,最常用工具类包。
lang3 目前最新版本是 3.12.0,最低要求 Java8 以上。相对于 lang 来说完全支持 Java8 的特性,废除了一些旧的 API。该版本无法兼容旧有版本,于是为了避免冲突改名为 lang3。
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.6</version> </dependency>
到此这篇关于一文带你深入了解Java String的不可变性的文章就介绍到这了,更多相关String不可变性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
java.lang.Instrument 代理Agent使用详细介绍
这篇文章主要介绍了java.lang.Instrument 代理Agent使用详细介绍的相关资料,附有实例代码,帮助大家学习参考,需要的朋友可以参考下2016-11-11深入学习Java单元测试(Junit+Mock+代码覆盖率)
在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,比如,代码覆盖率必须达到80%或 90%。下面我们就来详细学习下java单元测试吧2019-06-06spring整合JMS实现同步收发消息(基于ActiveMQ的实现)
本篇文章主要介绍了spring整合JMS实现同步收发消息(基于ActiveMQ的实现),具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-10-10
最新评论