String类的签名(JDK 8):

  public final class String implements java.io.Serializable, Comparable<String>, CharSequence { }

  String是不可变类,即String对象也是不可变对象。

  这意味着当修改一个String对象的内容时,JVM不会改变原来的对象,而是生成一个新的String对象。

 一、CharSequence 接口

  CharSequence API 解释,CharSequence的实例是一个包含“一个或者多个字符值(char values)”的可读序列。这个接口的功能就是对不同种类的字符序列提供统一的只读访问。

  CharSequence的实现类有String,StringBuffer,StringBuilder等。

  CharSequence接口要求实现的方法如下:

二、String类的字段

  2.1 private final char value[];

  存储组成字符串值的字符数组value,也是不可变的。

  

  2.2 private int hash;

  缓存String实例的hash值

  2.3 private static final long serialVersionUID = -6849794470754667710L;

  这个没太懂,注释解释如下:

  use serialVersionUID from JDK 1.0.2 for interoperability(互操作性)

  2.4 private static final ObjectStreamField[] serialPersistentFields =new ObjectStreamField[0];

  注释解释:Class String is special cased within the Serialization Stream Protocol

  StackOverflow上有讨论:why String in java does not override readObject?

  Strings, arrays and enums are special cases in serialization, and are not serialized through readObject/writeObject like other Objects are.

  Java中,字符串、数组和枚举在序列化方面是特殊的类,他们没有像其他对象一样通过readObject/writeObject进行序列化。

  2.5 public static final Comparator<String> CASE_INSENSITIVE_ORDER= new CaseInsensitiveComparator();

  CaseInsensitiveComparator类是一个String类中自己实现的比较器类。

  这个比较器对象通过compareToIgnoreCase对String对象进行排序的比较器。compareToIgnoreCase是String类中方法,功能是按字典顺序比较两个字符串,忽略大小写差异。返回正值,0,或者负值。

  该比较器是可序列化的。

  三、构造函数

  划线的表示本版JDK中已经被抛弃的。

  

  

  四、源自CharSequence接口的方法

  这些方法功能很明确,实现也并不复杂。

  

  五、源自Comparable的方法

  public int compareTo(String anotherString)

  按字典顺序比较两个字符串(上面有个字段也与比较有关,但与这个函数没有关系),这个是大小写敏感的,而且返回值也不是简单地以正负值表示比较结果。

  直接上源码:

public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value; int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}

  当String 的equals方法返回true时,该方法返回0.

  至于字典序到底怎么算大小,可以总结一下:

  小写字母>大写字母;同大小写,越靠字母表后面越大。

  ps:看完这个源码,我产生了疑惑,同一个类的不同实例竟然可以相互访问各自的private成员!!??

  是的,确实可以!!

  六、其它重要方法

  1、substring()——public String substring(int beginIndex);

public String substring(int beginIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
int subLen = value.length - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}

  sublen是索要生成的子串的长度,这个函数生成的子字符串为从内部的value字符数组中索引为beginIndex处到末尾处字符组成的字符串。

  如果beginIndex为0,则返回字符串本身;
  如果beginIndex不为0,则返回new String(value, beginIndex, subLen)
  下面上构造函数String(char value[], int offset, int count)源码:

public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count <= 0) {
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
if (offset <= value.length) {
this.value = "".value;
return;
}
}
// Note: offset or count might be near -1>>>1.
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.value = Arrays.copyOfRange(value, offset, offset+count);
}

  方法最后返回的是Arrays.copyOfRange(value, offset, offset+count),继续跟踪:

public static char[] copyOfRange(char[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
char[] copy = new char[newLength];
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}

  System.arraycopy()方法是一个native方法,它将指定源数组src中的数组从指定位置srcPos开始复制到目标数组dest的指定位置destPos,而length是所复制的长度。

public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos, int length)

  newLength是要复制的长度,copy是根据这个长度新建的char数组。这个copy将作为新建子串的value值。

  

  2、substring()——public String substring(int beginIndex, int endIndex)

public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}

  基本一样,subLen是根据endIndex和beginIndex得到的子串长度,需要注意endindex索引处的字符不包含在子串中。

Java String类源码的更多相关文章

  1. java.lang.String 类源码解读

    String类定义实现了java.io.Serializable, Comparable<String>, CharSequence 三个接口:并且为final修饰. public fin ...

  2. Java Properties类源码分析

    一.Properties类介绍 java.util.Properties继承自java.util.Hashtable,从jdk1.1版本开始,Properties的实现基本上就没有什么大的变动.从ht ...

  3. String 类源码分析

    String 源码分析 String 类代表字符序列,Java 中所有的字符串字面量都作为此类的实例. String 对象是不可变的,它们的值在创建之后就不能改变,因此 String 是线程安全的. ...

  4. java String部分源码解析

    String类型的成员变量 /** String的属性值 */ private final char value[]; /** The offset is the first index of the ...

  5. java Character类源码分析

    一.使用 构建Character对象: public class CharTest { public static void main(String[] args) { Character c1 = ...

  6. String类源码分析(JDK1.7)

    以下学习根据JDK1.7String类源代码做注释 public final class String implements java.io.Serializable, Comparable<S ...

  7. String类源码分析

    1.String类注释说明 /** * The {@code String} class represents character strings. All * string literals in ...

  8. String类源码解析

    1. String是使用char[]数组来存储的,并且String值在创建之后就不可以改变了.char[]数组的定义为: /** The value is used for character sto ...

  9. Java集合---Array类源码解析

    Java集合---Array类源码解析              ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...

随机推荐

  1. 访问项目时报错org.apache.jasper.JasperException: java.lang.NullPointerException

    错误信息:org.apache.jasper.JasperException: java.lang.NullPointerException 原因:项目依赖的jar包和tomcat容器的依赖jar包有 ...

  2. springboot 整合缓存(Ehcache或者reids)

    这里介绍Spring Boot结合JPA,MySQL和Ehcache实现缓存功能,提高程序访问效率. 一.Maven依赖 <!-- caching --> <dependency&g ...

  3. 《Flutter 实战》开源电子书

    <Flutter 实战>开源电子书 转 https://blog.csdn.net/OQjya206rsQ71/article/details/86619630   关于 Flutter ...

  4. mongodb 报错 not authorized on admin to execute command【 version 3.2.18 】

    mongodb version 3.2.18 测试问题: 分析: 从报错内容上看是权限不够,但不明了为什么,因为已经使用的超级用户权限: { "_id" : "admin ...

  5. C++ transform for_each

    #include<iostream>#include<vector>#include <list>#include <algorithm>#includ ...

  6. [Scikit-learn] 1.4 Support Vector Classification

    Ref: http://sklearn.lzjqsdd.com/modules/svm.html Ref: CS229 Lecture notes - Support Vector Machines ...

  7. 无法登录到Windows云服务器怎么办?

    当您的云服务器无法远程登录时,我们首先建议您使用VNC方式登录. 是否可以通过控制台远程登录 远程登录失败时,请首先尝试能否通过管理控制台,使用VNC方式登录弹性云服务器. 登录管理控制台. 选择“计 ...

  8. mysql一条语句实现插入或更新的操作

    ,),(,) ON DUPLICATE KEY UPDATE c=VALUES(c); 或者 INSERT INTO table (id,a,b,c) select id,a,b,c from xxx ...

  9. celery监控工具flower

    特性 用Celery事件实时监控 任务进程和历史 能够显示任务的详细信息(arguments, start time, runtime等) 图形化和统计 远程控制 查看worker状态和统计 关闭和重 ...

  10. OpenGL学习(4)——纹理(补)

    完成章节后练习 练习 1. Make sure only the happy face looks in the other/reverse direction by changing the fra ...