JDK8源码阅读(六) java.lang.String

一、类

1.1 类修饰符

A. string类表示字符串。Java程序中的所有字符串文字,如“ABC”,都是作为该类的实例实现的。字符串是常量;它们的值在创建后不能更改。字符串缓冲区支持可变字符串。因为字符串对象是不可变的,所以可以共享它们;

B.  类字符串包括检查序列中单个字符、比较字符串、搜索字符串、提取子字符串以及创建字符串副本(所有字符都转换为大写或小写)的方法。大小写映射基于字符类指定的Unicode标准版本;

C. Java语言为字符串级联操作符(+)提供了特殊的支持,并将其他对象转换为字符串。字符串连接是通过StringBuilder(或StringBuffer)类及其append方法实现的。字符串转换是通过对象ToString实现的,由对象定义并由Java中的所有类继承。有关字符串连接和转换的附加信息,请参见Java语言规范戈斯林、Joy和斯梯尔;

D. 除非另有说明,否则将空参数传递给此类中的构造函数或方法将导致引发NullPointerException;

E. 字符串表示采用UTF-16格式的字符串,其中补充字符由代理项对表示(有关详细信息,请参阅字符类中的Unicode字符表示部分)。索引值指的是字符代码单位,因此补充字符在字符串中使用两个位置;

F. 字符串类除了提供处理Unicode代码单元(即char值)的方法外,还提供了处理Unicode代码点(即字符)的方法;

G.  String str = "abc"; 和  char data[] = {'a', 'b', 'c'};   String str = new String(data); 是相等的。

 

1.2 类结构图

 

二、内部类 

2.1 CaseInsensitiveComparator

具体参见链接TODO 

 

三、字段

3.1 字段列表

 

3.2 字段修饰符

 

3.3 字段详解

3.3.1 serialVersionUID

A. 使用JDK 1.0.2中的serialVersionUID实现互操作性;

 

3.3.2 hash

A. 缓存字符串的哈希码, 默认为0;

 

3.3.3 value[]

A. 该值用于字符存储;

 

3.3.4 serialPersistentFields

A. 类字符串在序列化流协议中是特殊情况。根据对象序列化规范第6.2节“流元素”,将字符串实例写入ObjectOutputStream;

 

3.3.5 CASE_INSENSITIVE_ORDER

 A. 按CompareToIgnoreCase对字符串对象排序的比较器。这个比较器是可序列化的。请注意,这个比较器不考虑区域设置,并且会导致某些区域设置的排序不令人满意。java.text包提供了排序器,允许区分区域设置的排序;

 

四、方法

4.1 方法列表

 

 

注:如上图,共有n个方法。 

        绿色打开的锁代表是public,  红色关闭的代表是private, 灰色的钥匙代表的protected。

 

4.2 方法修饰符

 


4.3 方法详解

4.3.0 代码块

无。

 

4.3.1 构造函数

4.3.1.1 String()

A. 初始化新创建的字符串对象,使其表示空字符序列。

B. 注意,不需要使用此构造函数,因为字符串是不可变的。 

4.3.1.2 String(String original)

A. 初始化新创建的字符串对象,使其表示与参数相同的字符序列;

B. 换句话说,新创建的字符串是参数字符串的副本。除非需要原始的显式副本,否则不必使用此构造函数,因为字符串是不可变的。 

4.3.1.3 String(char value[])

A. 分配一个新字符串,以便它表示当前包含在字符数组参数中的字符序列。复制字符数组的内容;随后对字符数组的修改不会影响新创建的字符串。 

B. 该方法调用java.util.Arrays的copyOf方法,复制指定的数组,截断或填充空字符(如有必要),使副本具有指定的长度。对于在原始数组和副本中都有效的所有索引,这两个数组将包含相同的值。对于副本中有效但不是原始索引的任何索引,副本将包含'\u000'。只有当指定的长度大于原始数组的长度时,才会存在此类索引。在此处该方法内部大致逻辑如下:根据原始字符数组的长度创建一个新的字符数组,然后调用java.lang.System的arraycopy方法,将原始数组、新的字符数组、长度传递过去。

C. 该方法是一个native方法,不是java实现。大致操作为: 从指定的源数组(从指定位置开始)将数组复制到目标数组的指定位置。数组组件的子序列从SRC引用的源数组复制到DEST引用的目标数组。复制的组件数等于长度参数。源数组中位置srcpos到srcpos+length-1的组件分别通过目标数组的destpos+length-1复制到位置destpos。

 

4.3.1.4 String(char value[], int offset, int count)

A. 分配包含字符数组参数子数组中的字符的新字符串。offset参数是子数组第一个字符的索引,count参数指定子数组的长度。子数组的内容将被复制;随后对字符数组的修改不会影响新创建的字符串。

B. 该方法的大致内容如下: 如果偏移量和或长度小于零,则不合法;如果取的长度等于零,则将原始字符数组改为空串的字符数组并返回;如果偏移量和截取长度之和大于字符数组长度,则不合法;符合条件的情况下,调用java.util.Arrays的copyOfRange方法,将原始数组、偏移量、偏移量与长度之和传递过去。

C.将指定数组的指定范围复制到新数组中。范围(从)的初始索引必须介于0和original.length之间(包括0和original.length)。原始[From]处的值放入副本的初始元素中(除非From==Original.Length或From==To)。原始数组中后续元素的值将放置到副本中的后续元素中。范围(到)的最后一个索引必须大于或等于From,它可以大于original.length,在这种情况下,将在索引大于或等于original.length-From的副本的所有元素中放置'\u000'。返回的数组的长度将为至-自。 最后调用java.lang.System的arraycopy方法。

 

4.3.1.5 String(int[] codePoints, int offset, int count) 【TODO】

A. 分配一个新字符串,该字符串包含来自unicode码位数组参数子数组的字符。offset参数是子数组第一个代码点的索引,count参数指定子数组的长度。子数组的内容转换为chars;对int数组的后续修改不会影响新创建的字符串。 

B. 该方法的大致内容如下: 如果偏移量和或长度小于零,则不合法;如果取的长度等于零,则将原始字符数组改为空串的字符数组并返回;如果偏移量和截取长度之和大于字符数组长度,则不合法;符合条件的情况下,TODO

 

4.3.1.6 String(byte ascii[], int hibyte, int offset, int count)[TODO]

A. 这是一个过时方法。分配从8位整数值数组的子数组构造的新字符串。offset参数是子数组第一个字节的索引,count参数指定子数组的长度。子数组中的每个字节都转换为上面方法中指定的字符。

B. 该方法的具体内容如下:TODO 

 

4.3.1.7 String(byte ascii[], int hibyte) [TODO]

A. 分配包含从8位整数值数组构造的字符的新字符串。结果字符串中的每个字符都是由字节数组中相应的组件B构造的。TODO

 

4.3.1.8 String(byte bytes[], int offset, int length, String charsetName)[TODO]

A. 通过使用指定的字符集对指定的字节子数组进行解码来构造新的字符串。新字符串的长度是字符集的函数,因此可能不等于子数组的长度。

B. 未指定给定字符集中给定字节无效时此构造函数的行为。当需要对解码过程进行更多控制时,应使用java.nio.charset.charsetdecoder类。

 

4.3.1.9 String(byte bytes[], int offset, int length, Charset charset) [TODO]

A. 通过使用指定的字符集对指定的字节子数组进行解码来构造新的字符串。新字符串的长度是字符集的函数,因此可能不等于子数组的长度。

B. 此方法总是用此字符集的默认替换字符串替换格式错误的输入和不可映射的字符序列。当需要对解码过程进行更多控制时,应使用java.nio.charset.charsetdecoder类。

 

4.3.1.10 String(byte bytes[], String charsetName) [TODO]

A.  通过使用指定的字符集对指定的字节数组进行解码来构造新的字符串。新字符串的长度是字符集的函数,因此可能不等于字节数组的长度。

B. 未指定给定字符集中给定字节无效时此构造函数的行为。当需要对解码过程进行更多控制时,应使用java.nio.charset.charsetdecoder类。

 

4.3.1.11 String(byte bytes[], Charset charset) [TODO]

A. 通过使用指定的字符集对指定的字节数组进行解码来构造新的字符串。新字符串的长度是字符集的函数,因此可能不等于字节数组的长度。

B. 此方法总是用此字符集的默认替换字符串替换格式错误的输入和不可映射的字符序列。当需要对解码过程进行更多控制时,应使用java.nio.charset.charsetdecoder类。

 

4.3.1.12 String(byte bytes[], int offset, int length) [TODO]

A. 通过使用平台的默认字符集对指定的字节子数组进行解码来构造新的字符串。新字符串的长度是字符集的函数,因此可能不等于子数组的长度。

B. 未指定给定字节在默认字符集中无效时此构造函数的行为。当需要对解码过程进行更多控制时,应使用java.nio.charset.charsetdecoder类。

 

4.3.1.13 String(byte bytes[]) [TODO]

A. 通过使用平台的默认字符集对指定的字节数组进行解码来构造新的字符串。新字符串的长度是字符集的函数,因此可能不等于字节数组的长度。

B. 未指定给定字节在默认字符集中无效时此构造函数的行为。当需要对解码过程进行更多控制时,应使用java.nio.charset.charsetdecoder类。

 

4.3.1.14 String(StringBuffer buffer)

A. 这是一个同步方法。分配包含字符串缓冲区参数中当前包含的字符序列的新字符串。复制字符串缓冲区的内容;随后对字符串缓冲区的修改不会影响新创建的字符串。

B. 该方法的大致逻辑如下: 以该StringBuffer对象作为锁,同步代码块中调用java.util.Arrays的copyOf方法,将StringBuffer的value和长度传递过去。

C. java.util.Arrays的copyOf方法的内部大致逻辑如下:复制指定的数组,截断或填充空字符(如有必要),使副本具有指定的长度。对于在原始数组和副本中都有效的所有索引,这两个数组将包含相同的值。对于副本中有效但不是原始索引的任何索引,副本将包含'\u000'。只有当指定的长度大于原始数组的长度时,才会存在此类索引。然后会调用java.lang.System的arraycopy方法,略。

 

4.3.1.15 String(StringBuilder builder)

A. 分配包含字符串生成器参数中当前包含的字符序列的新字符串。将复制字符串生成器的内容;随后对字符串生成器的修改不会影响新创建的字符串。

B. 提供此构造函数是为了方便迁移到StringBuilder。通过ToString方法从字符串生成器中获取字符串可能运行得更快,通常是首选方法。

 

4.3.1.16 String(char[] value, boolean share)

A. 这是一个包私有的构造函数。 为速度共享值数组的包私有构造函数。始终应使用share==true调用此构造函数。需要一个单独的构造函数,因为我们已经有了一个公共字符串(char[])构造函数,它可以复制给定的char[]。

 

4.3.2 普通方法

4.3.2.1 length()

A. 返回此字符串的长度。长度等于字符串中的Unicode代码单元数;

 

4.3.2.2 isEmpty()

A. 如果且仅当字符串长度为0时返回true;

 

4.3.2.3 charAt(int index)

A. 返回指定索引处的char值。索引的范围从0到length()-1。对于数组索引,序列的第一个char值位于索引0,下一个char值位于索引1,依此类推。如果索引指定的char值是代理项,则返回代理项值;

 

4.3.2.4 codePointAt(int index)[TODO]

A. 返回指定索引处的字符(Unicode码位)。索引引用字符值(Unicode代码单位),范围从0到length()-1。

B. 如果在给定索引处指定的char值在高代理范围内,则以下索引小于此字符串的长度,并且以下索引处的char值在低代理范围内,则返回与此代理对对应的补充代码点。否则,返回给定索引处的char值。

 

4.3.2.5 codePointBefore(int index) [TODO]

A. 返回指定索引之前的字符(Unicode码位)。索引引用了字符值(Unicode代码单位),其范围从1到长度。

B. 如果(index-1)处的char值在低代理范围内,(index-2)不为负,并且(index-2)处的char值在高代理范围内,则返回代理对的补充码位值。如果索引-1处的char值是不成对的低代理项或高代理项,则返回代理项值。

 

4.3.2.6 codePointCount(int beginIndex, int endIndex) [TODO]

A. 返回此字符串指定文本范围内的Unicode代码点数。文本范围从指定的beginindex开始,扩展到index endindex-1处的char。因此,文本范围的长度(以字符为单位)是endindex beginindex。文本范围内未配对的代理项将作为每个代码点计数。

 

4.3.2.7 offsetByCodePoints(int index, int codePointOffset)[TODO]

A.返回此字符串中的索引,该索引与给定索引之间的偏移量为codepointoffset代码点。在索引和代码点偏移量计数给出的文本范围内,未成对的代理项各作为一个代码点。 

 

4.3.2.8 getChars(char dst[], int dstBegin)

A. 将此字符串中的字符从dstbegin开始复制到dst。此方法不执行任何范围检查;

 

4.3.2.9 getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)

A. 将此字符串中的字符复制到目标字符数组中。

B. 要复制的第一个字符位于索引srcbegin;要复制的最后一个字符位于索引srcend-1(因此要复制的字符总数为srcend srcbegin)。将字符复制到DST的子阵列中,从索引DSBEGIN开始,到索引处结束: dstBegin + (srcEnd-srcBegin) - 1.

 

4.3.2.10 getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)

A. 这是一个过时方法。

B. 将此字符串中的字符复制到目标字节数组中。每个字节接收相应字符的8个低位。每个字符的八个高阶位不会被复制,也不会以任何方式参与传输。

C. 要复制的第一个字符位于索引srcbegin;要复制的最后一个字符位于索引srcend-1。要复制的字符总数为srcend srcbegin。将转换为字节的字符复制到DST的子数组中,从索引dstbegin开始,到索引处结束:dstBegin + (srcEnd-srcBegin) - 1.

 

4.3.2.11 getBytes(String charsetName)

A.  

 

 

 

五. JDK8源码阅读系列链接

  1. JDK8源码阅读(一) java.util.Object
  2. JDK8源码阅读(二) java.util.Objects
  3. JDK8源码阅读(三) java.io.Serializable   
  4. JDK8源码阅读(四) java.lang.Comparable
  5. JDK8源码阅读(五) java.lang.CharSequence
  6. JDK8源码阅读(六) java.lang.String

注: 今年要把JDK的一些基本的类的源码整理出来,欢迎大家指正和讨论。

         如果有错误的地方,欢迎各位老师指正。

         如果您觉得还不错,点个赞的话  我会很感激的,谢谢~

         转载请注明链接来源即可。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值