String类表示字符串。Java程序中的所有字符串字面值,例如"abc",都是作为该类的实例实现的。
字符串是常量;它们的值在创建后不能更改。字符串缓冲区支持可变字符串。因为String对象是不可变的,所以它们可以被共享。
String类实现了三个接口:
- java.io.Serializable:序列化接口没有方法或字段,仅用于标识可序列化的语义。
- Comparable<String>:这个接口对实现它的每个类的对象施加了一个总的排序。这种排序被称为类的自然排序,而类的compareTo方法被称为其自然比较方法。
- CharSequence:CharSequence是一个可读的字符值序列。这个接口提供了对许多不同类型的字符序列的统一的只读访问。
String类有两个实例变量:
- private final char value[];用于字符串的存储(注意final修饰符);
- private int hash:用于缓存字符串的哈希码;
三个静态变量:
- private static final long serialVersionUID = -6849794470754667710L :在 Java 中,serialVersionUID 是一个用于标识序列化类版本的特殊字段。它是一个长整型数值,通常在实现 Serializable 接口的类中使用,用于确保序列化和反序列化的一致性。
- private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];类字符串在序列化流协议中是特殊的。根据对象序列化规范第6.2节“流元素”,将字符串实例写入ObjectOutputStream中。(官方文档中的解释,暂时没搞懂是干嘛的)
- public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();一个比较器,按compareToIgnoreCase排序字符串对象。这个比较器是可序列化的。
一.构造器
String类中有很多的有参构造器和一个无参构造器,由于String对象是不可变的,所以无参构造器的使用其实是没有必要的。
有参构造器(显示的都是参数):
- (String original):初始化新创建的String对象,使其表示与参数相同的字符序列;换句话说,新创建的字符串是参数字符串的副本。除非需要原始的显式副本,否则不需要使用此构造函数,因为string是不可变的。
- (char value[]):分配一个新的String,使其表示当前包含在字符数组参数中的字符序列。内部调用Arrays.copyof方法赋值给实例变量value
- (char value[], int offset, int count):分配一个新的String,offset参数是子数组第一个字符的索引,count参数指定子数组的长度。底层是参数校验并调用Arrays.copyOfRange
- (int[] codePoints, int offset, int count):与3相同,不过第一个参数为int数组,底层为三步,首先进行参数的校验,然后确定char[] 的精确大小,最后对char[]进行赋值
- (byte ascii[], int hibyte, int offset, int count):分配一个由8位整数值数组的子数组构造的新String。offset参数是子数组第一个字节的索引,count参数指定子数组的长度。子数组中的每个字节被转换为上面方法中指定的字符。有@Deprecated注解标识,表示此方法已废弃、暂时可用,但以后此类或方法都不会再更新、后期可能会删除,建议后来人不要调用此方法。
- (byte ascii[], int hibyte):底层是调用构造器5,同样有@Deprecated注解
- (byte bytes[], int offset, int length, String charsetName):底层通过调用StringCoding.decode方法来通过指定的字符集来对字符数组进行解码。当需要对解码过程进行更多控制时,应该使用charsetdecoder类。
- (byte bytes[], int offset, int length, Charset charset):与构造器7相同,不过一个是调用字符集名称,一个是字符集
- (byte bytes[], String charsetName) && (byte bytes[], Charset charset):分别是偏移量为0的7和8
- (byte bytes[], int offset, int length) && (byte bytes[]):与上面类似。
- (StringBuffer buffer):底层调用Arrays.copyof方法分配一个新的字符串,通过synchronized加锁来实现线程安全
- (StringBuilder builder):与11底层相同,但是未加锁
- (char[] value, boolean share):与2相同,但是底层并没有对share做任何校验
二.实例方法
- int length( ):返回该字符串的长度
- boolean isEmpty():判断字符串是否为空
- char charAt(int index):返回指定索引处的字符
- int codePointAt(int index):此方法接受一个int类型参数索引,该索引表示要返回其unicode值的字符的索引。
- int codePointBefore(int index):方法返回字符串中指定索引之前的字符的Unicode值。
- int codePointCount(int beginIndex, int endIndex):返回此字符串的指定文本范围内的Unicode码点数。
- int offsetByCodePoints(int index, int codePointOffset):返回此 String 中与给定索引偏移 codePointOffset 代码点的索引
- void getChars(char dst[], int dstBegin):将字符串中的字符从dst开始复制到dst[]中。
- void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin):将此字符串中的字符复制到目标字符数组中。与方法8相同,底层都是调用System.arraycopy()方法(该方法是一个native方法),不同的是,方法8没有任何数据检查,此方法有
- void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin):将此字符串中的字符复制到目标字节数组中。每个字节接收相应字符的8个低阶位。每个字符的8个高阶位不被复制,也不以任何方式参与传输。有@Deprecated注解
- byte[] getBytes(String charsetName):使用命名字符集将该字符串编码为字节序列,并将结果存储到新的字节数组中
- byte[] getBytes(Charset charset):同上
- byte[] getBytes():不显式指定字符集
- boolean equals(Object anObject):首先判断两个比较的对象是否为同一个对象,若为则直接返回true。若不为同一对象,则从低位到高位逐一比较是否相等。
- boolean contentEquals(StringBuffer sb):底部调用方法17
- boolean nonSyncContentEquals(AbstractStringBuilder sb):没有保证线程安全的比较方法,底层也是从低到高依次比较
- boolean contentEquals(CharSequence cs):内部进行三种操作,首先如果实现了AbstractStringBuilder接口,如果是StringBuffer,进行加锁然后调用16,如果是StringBuilder,则不加锁直接调用16,其次如果是字符串,则调用14, 最后CharSequence类型则从低到高依次比较
- boolean equalsIgnoreCase(String anotherString):同一对象直接返回,不同对象则先判断空值,后比较长度,再调用22(ignoreCase为true)
- int compareTo(String anotherString):比较两个字符串,若两个字符串相等则返回0,若不相等,从低到高比较,若this字符串与anotherString不同,比较该位字符的大小,返回(this字符串当前字符值-another当前字符值),若比较完的部分相等,则最后返回(this字符串的长度-another的长度)
- int compareToIgnoreCase(String str):此方法返回一个整数,其符号为调用compareTo的字符串的规范化版本,其中通过对每个字符调用character. tolowercase (character . touppercase (character))消除了大小写差异。
- boolean regionMatches(boolean ignoreCase, int toffset,String other, int ooffset, int len):要比较的这个String对象的子字符串从索引tooffset偏移开始,长度为length。要比较的other的子字符串从索引ooffset偏移开始,长度为len。
- boolean regionMatches(boolean ignoreCase, int toffset,String other, int ooffset, int len):与21相同,不过会根据传入的ignoreCase来判断是否忽略大小写
- boolean startsWith(String prefix, int toffset):从指定索引开始的此字符串的子字符串是否以指定的前缀开始。
- boolean startsWith(String prefix):底层调用23传入偏移量为0
- boolean endsWith(String suffix):底层调用23,偏移量为this.value.length-suffix.value.length,即在末尾匹配
- int hashCode():如果hash值不为0,则直接返回此字符串的散列码。不为零并且长度大于0,重新计算hash码,String对象的哈希码计算为S [0]*31^(n-1) + S [1]*31^(n-2) +…+ s (n - 1)
- int indexOf(int ch):底层调用28,索引值为0
- int indexOf(int ch, int fromIndex):返回该字符串中指定字符第一次出现的索引,从指定索引处开始搜索。索引值为负数则按0看待,索引值大于该字符串长度,则返回-1,查询的字符范围不在unicode编码值以内(65536)则调用29。
- int indexOfSupplementary(int ch, int fromIndex):处理(罕见的)带有补充字符的indexOf调用。
- int lastIndexOf(int ch):底层调用31,索引值为value.length-1
- int lastIndexOf(int ch, int fromIndex):返回该字符串中指定字符最后一次出现的索引,从指定索引处倒序搜索。fromIndex越界则取长度值,与28相同,查询的字符范围不在unicode编码值以内(65536)则调用32。
- int lastIndexOfSupplementary(int ch, int fromIndex):处理(罕见的)带有补充字符的indexOf调用。
- 之后还有八个方法也是属于字符串查找一类,总体结构与前面这几种无明显差异,只是具体实现方法有所区别,另外,第一次见到了Java中循环标签的使用
- String substring(int beginIndex):返回一个字符串,该字符串是此字符串的子字符串。子字符串从指定索引处的字符开始,并扩展到该字符串的末尾。返回的是一个新的字符串对象
- String substring(int beginIndex, int endIndex):返回一个字符串,该字符串是此字符串的子字符串。子字符串从指定的beginIndex开始,并扩展到索引endIndex - 1处的字符。与34相同,底层都是调用构造器3返回一个新的字符串对象
- CharSequence subSequence(int beginIndex, int endIndex):底层调用34
- String concat(String str):将指定的字符串连接到此字符串的末尾。
- String replace(char oldChar, char newChar):返回一个字符串,将此字符串中出现的所有oldChar替换为newChar。如果字符oldChar没有出现在这个String对象表示的字符序列中,则返回对这个String对象的引用。否则,将返回一个String对象
- boolean matches(String regex):用于检测字符串是否匹配给定的正则表达式
- boolean contains(CharSequence s):当且仅当此字符串包含指定的字符值序列时返回true。底层是通过调用indexof方法后取返回值与-1比较
- String replaceFirst(String regex, String replacement):将与给定正则表达式匹配的子字符串的第一个匹配项替换为给定替换项
- String replaceAll(String regex, String replacement):将此字符串中与给定正则表达式匹配的每个子字符串替换为给定替换项
- String replace(CharSequence target, CharSequence replacement):将此字符串中与文字目标序列匹配的每个子字符串替换为指定的文字替换序列。
- String[] split(String regex, int limit):按照指定的分隔符regex,分隔字符串String;分隔结果为String[ ]格式。limit 参数通过控制分割次数从而影响分割结果。如果表达式与输入的任何部分都不匹配,则结果数组只有一个元素,即这个字符串。
- String[] split(String regex):调用44,传入的limit为0,表示将会以最大分割次数分割,但是分割结果会舍弃末位的空串
- String toLowerCase(Locale locale):使用给定Locale的规则将此String中的所有字符转换为小写。大小写映射基于字符类指定的Unicode标准版本。由于大小写映射并不总是1:1的字符映射,因此生成的String可能与原始String的长度不同。其中参数Locale对象表示特定的地理、政治或文化区域。需要区域设置来执行任务的操作称为区域设置敏感的操作,它使用区域设置为用户定制信息。例如,显示数字是一种对语言环境敏感的操作——应该根据用户所在国家、地区或文化的习俗和惯例对数字进行格式化。源码中大多是对参数进行校验和对特殊的语言地区(比如希腊语和拉丁语)进行处理,虽然行数很多,但是主观感觉不需要较真解读。
- String toLowerCase():底层调用46,传入的Local对象为Local.getDefault()根据本机地址自动获取语言地区。
- String toUpperCase(Locale locale):使用给定Locale的规则将此String中的所有字符转换为大写。
- String toUpperCase():底层调用48,传入的Local对象为Local.getDefault()根据本机地址自动获取语言地区。
- String trim():返回一个字符串,其值为此字符串,删除任何前导和末尾的空格。如果此String对象表示空字符序列,或者此String对象表示的字符序列的第一个字符和最后一个字符的代码都大于'\u0020'(空格字符),则返回对此String对象的引用。
- String toString():返回这个字符串对象本身
- char[] toCharArray():将此字符串转换为新的字符数组。由于导致类的初始化顺序问题底层不采用Arrays.copyof()而是采用System.arraycopy()(官方文档说明,不是很懂,况且Arrays.copyof底层就是调用的System.arraycopy()方法)
- String intern():返回字符串对象的规范表示形式。字符串池最初为空,由String类私有地维护。当调用intern方法时,如果池中已经包含一个由equals(object)方法确定的与此string对象相等的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对该String对象的引用。由此可见,对于任意两个字符串s和t, s.t inintern () == t.t inintern()当且仅当s.s equals(t)为真时为真。同时,该方法也是一个本地方法,有native关键字修饰
三.静态方法
- String join(CharSequence delimiter, CharSequence... elements):返回一个由CharSequence元素的副本与指定分隔符的副本连接而成的新String。官方案例:String message = String. join("-", "Java", "is", "cool"); // message returned is: "Java-is-cool"
- String join(CharSequence delimiter,Iterable<? extends CharSequence> elements):与1底层代码保持一致,不过1的传入参数为多参数形式,而此方法的传参为一个迭代器对象,例如LinkedList或者LinkedHashSet
- String format(String format, Object... args):返回指定的格式化的字符串。Format参数为格式字符串语法如下:%[argument_index$][flags][width][.precision]conversion “[]”里的参数表示可选。可选的 argument_index :下标是一个十进制整数,用于表明参数在参数列表中的位置。可选的 flags 标志是修改输出格式的字符集。有效标志的集合取决于转换类型。可选 width 最小宽度是一个非负十进制整数,表明要向输出中写入的最少字符数。可选 precision 是一个非负十进制整数,通常用来限制字符数。特定行为取决于转换类型。所需的 conversion转换方式是一个表明应该如何格式化参数的字符。给定参数的有效转换集合取决于参数的数据类型
- String format(Locale l, String format, Object... args):使用指定的语言环境、格式字符串和参数返回格式化字符串。
- String valueOf():该方法参数类型丰富,大多是基于构造器或者使用相应数据类型的.toString()方法,大同小异。
四.静态内部类
- CaseInsensitiveComparator:实现了Comparator<String>和java.io.Serializable接口,有一个静态变量serialVersionUID
- int compare(String s1, String s2):和实例方法19中的比较规则类似,不过会先将当前字符值都转为大写比较一遍,再都转为小写比较一遍
- Object readResolve():替换反序列化的对象