public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/**char数组用于字符的存储 */
private final char value[]; /** 缓存string的hash码 */
private int hash; // Default to 0 public String() {/**无参构造函数,打印值为""*/
this.value = new char[0];
} public String(String original) {/**字符值和hash值均为参数的值*/
this.value = original.value;
this.hash = original.hash;
} public String(char value[]) {/**Arrays.copyOf()方法返回一个新构造的
char数组*/
this.value = Arrays.copyOf(value, value.length);
} public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
// 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);
} /**传入代码点来构造String对象,代码点和代码单元相关内容可自行查阅资料,或者看我另一篇随笔深入学习Java中的字符串,代码点和代码单元*/
public String(int[] codePoints, int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
// Note: offset or count might be near -1>>>1.
if (offset > codePoints.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
} final int end = offset + count; /**计算char数组的真实大小,一个代码点有可能需要用2个char即2个代码单元表示*/
int n = count;
for (int i = offset; i < end; i++) {
int c = codePoints[i];
if (Character.isBmpCodePoint(c))/**此代码点为基本字符代码点*/
continue;
else if (Character.isValidCodePoint(c))/**此代码点为有效代码点,即辅助字符代码点,此时一个代码点需要用2个char即2个代码单元表示,n++*/
n++;
else throw new IllegalArgumentException(Integer.toString(c));
} /**分配并填充字符数组*/
final char[] v = new char[n]; for (int i = offset, j = 0; i < end; i++, j++) {
int c = codePoints[i];
if (Character.isBmpCodePoint(c))
v[j] = (char)c;
else
Character.toSurrogates(c, v, j++);
} this.value = v;
} /**返回指定下标的字符*/
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
} /**返回指定下标的代码点*/
public int codePointAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return Character.codePointAtImpl(value, index, value.length);
} public boolean equals(Object anObject) {
if (this == anObject) {
return true;/**如果是同一个对象,直接返回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;
} public boolean contentEquals(StringBuffer sb) {
synchronized (sb) {/**锁定StringBuffer对象,防止修改*/
return contentEquals((CharSequence) sb);
}
} public boolean equalsIgnoreCase(String anotherString) {
return (this == anotherString) ? true
: (anotherString != null)
&& (anotherString.value.length == value.length)
&& regionMatches(true, 0, anotherString, 0, value.length);
} /**计算并返回hsah码*/
public int hashCode() {
int h = hash;/**默认是0*/
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
} /**字串为新对象*/
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);
}
/**连接字符串*/
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);/**将str内的字符依次存放到buf数组中,下标从len开始*/
return new String(buf, true);/**返回新生成的对象*/
} /**trim()方法将字符串首尾的ascii码数值小于或等于空格的字符删除*/
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */ while ((st < len) && (val[st] <= ' ')) {/**从字符串首个字符开始判断ascii是否小于或等于空格,若小于或等于,计数++*/
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {/**从字符串最后一个字符开始判断ascii是否小于或等于空格,若小于或等于,计数--*
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
} /**返回自身对象的引用*/
public String toString() {
return this;
} /**和toString()唯一区别就是先判断对象是否为空*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

java String源码学习的更多相关文章

  1. String源码学习

    String源码学习 零散的收获 数组的元素类型可以通过getComponentType来获取到 子类型的数组可以赋值给父类型的数组,.但是并不存在继承关系.数组的父类是Object. 通过声明如下代 ...

  2. 程序兵法:Java String 源码的排序算法(一)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 <程序兵法:Java Str ...

  3. java Integer 源码学习

    转载自http://www.hollischuang.com/archives/1058 Integer 类在对象中包装了一个基本类型 int 的值.Integer 类型的对象包含一个 int 类型的 ...

  4. 基于JDK1.8的String源码学习笔记

    String,可能是学习Java一上来就学习的,经常用,但是却往往只是一知半解,甚至API有时也得现查.所以还是老规矩,倒腾源码. 一.java doc 这次首先关注String的doc,因为其实作为 ...

  5. Java集合源码学习(一)集合框架概览

    >>集合框架 Java集合框架包含了大部分Java开发中用到的数据结构,主要包括List列表.Set集合.Map映射.迭代器(Iterator.Enumeration).工具类(Array ...

  6. java BigInteger源码学习

    转载自http://www.hollischuang.com/archives/176 在java中,有很多基本数据类型我们可以直接使用,比如用于表示浮点型的float.double,用于表示字符型的 ...

  7. Java集合源码学习(三)LinkedList分析

    前面学习了ArrayList的源码,数组是顺序存储结构,存储区间是连续的,占用内存严重,故空间复杂度很大.但数组的二分查找时间复杂度小,为O(1),数组的特点是寻址容易,插入和删除困难.今天学习另外的 ...

  8. Java集合源码学习(二)ArrayList分析

    >>关于ArrayList ArrayList直接继承AbstractList,实现了List. RandomAccess.Cloneable.Serializable接口,为什么叫&qu ...

  9. Java集合源码学习(三)LinkedList

    前面学习了ArrayList的源码,数组是顺序存储结构,存储区间是连续的,占用内存严重,故空间复杂度很大.但数组的二分查找时间复杂度小,为O(1),数组的特点是寻址容易,插入和删除困难.今天学习另外的 ...

随机推荐

  1. IOS被遗忘的知识

    IOS ARC项目使用非ARC文件 1.自己的旧项目没有使用ARC,可是引入的第三方库却是使用了ARC的. 对于第一个情况,给採用了ARC的源文件,加入-fobjc-arc选项 2.自己的新项目使用了 ...

  2. libvlc media player in C# (part 2)

    原文 http://www.helyar.net/2009/libvlc-media-player-in-c-part-2/ I gave some simplified VLC media play ...

  3. System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(string, string)已过时的解决办法

    FormsAuthentication.HashPasswordForStoringInConfigFile 方法是一个在.NET 4.5中已经废弃不用的API,参见: https://msdn.mi ...

  4. 因下面文的损坏或丢失windows/system32/config/system 解决方法

    这是因为你电脑的初始化文件遭破坏所致.导致破坏的原因也可能是病毒或其它原因. 因为Windows启动须要读取Syatem.ini,Win.ini和注冊表文件,假设C盘根文件夹下有config.sys, ...

  5. leetcode第24题--Reverse Nodes in k-Group

    problem: Given a linked list, reverse the nodes of a linked list k at a time and return its modified ...

  6. Windows环境搭建Web自动化测试框架Watir

    Windows环境搭建Web自动化测试框架Watir 一.前言     Web自动化测试一直是一个比较迫切的问题,对于现在web开发的敏捷开发,却没有相对应的敏捷测试,故开此主题,一边研究,一边将We ...

  7. ComponentName意思

    ComponentNameActivity Intent i=new Intent(); i.setComponent(new ComponentName(String packageName,Str ...

  8. MEF高级进阶

    MEF高级进阶   好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四 ...

  9. 处理程序“svc-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”

    HTTP 错误 404.3 - Not Found 由于扩展配置问题而无法提供您请求的页面.如果该页面是脚本,请添加处理程序.如果应下载文件,请添加 MIME 映射. 解决办法:以管理员运行命令:C: ...

  10. Android中怎么去除标题栏详解

    怎么出去标题栏,我再另一个博客中亦有实例在这里再详细的解释一下,也让自己能更加巩固最简单也是小重要的东西. 这里有两种方法是比较好的... 第一种: 首先,在values中建一个theme.xml 代 ...