java String源码学习
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源码学习的更多相关文章
- String源码学习
String源码学习 零散的收获 数组的元素类型可以通过getComponentType来获取到 子类型的数组可以赋值给父类型的数组,.但是并不存在继承关系.数组的父类是Object. 通过声明如下代 ...
- 程序兵法:Java String 源码的排序算法(一)
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 <程序兵法:Java Str ...
- java Integer 源码学习
转载自http://www.hollischuang.com/archives/1058 Integer 类在对象中包装了一个基本类型 int 的值.Integer 类型的对象包含一个 int 类型的 ...
- 基于JDK1.8的String源码学习笔记
String,可能是学习Java一上来就学习的,经常用,但是却往往只是一知半解,甚至API有时也得现查.所以还是老规矩,倒腾源码. 一.java doc 这次首先关注String的doc,因为其实作为 ...
- Java集合源码学习(一)集合框架概览
>>集合框架 Java集合框架包含了大部分Java开发中用到的数据结构,主要包括List列表.Set集合.Map映射.迭代器(Iterator.Enumeration).工具类(Array ...
- java BigInteger源码学习
转载自http://www.hollischuang.com/archives/176 在java中,有很多基本数据类型我们可以直接使用,比如用于表示浮点型的float.double,用于表示字符型的 ...
- Java集合源码学习(三)LinkedList分析
前面学习了ArrayList的源码,数组是顺序存储结构,存储区间是连续的,占用内存严重,故空间复杂度很大.但数组的二分查找时间复杂度小,为O(1),数组的特点是寻址容易,插入和删除困难.今天学习另外的 ...
- Java集合源码学习(二)ArrayList分析
>>关于ArrayList ArrayList直接继承AbstractList,实现了List. RandomAccess.Cloneable.Serializable接口,为什么叫&qu ...
- Java集合源码学习(三)LinkedList
前面学习了ArrayList的源码,数组是顺序存储结构,存储区间是连续的,占用内存严重,故空间复杂度很大.但数组的二分查找时间复杂度小,为O(1),数组的特点是寻址容易,插入和删除困难.今天学习另外的 ...
随机推荐
- ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)
原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!) 继上篇:ORACLE P ...
- 快速构建Windows 8风格应用11-语义缩放
原文:快速构建Windows 8风格应用11-语义缩放 本篇博文主要介绍为什么需要语义缩放.什么是语义缩放.如何构建语义缩放. 为什么需要语义缩放 如果用过Windows 8系统的开发者都知道在Win ...
- jmeter 控制器
Critical Section Controller :
- 【COCOS2DX-游戏开发之三四】cocos2dx 3.0 TableView特殊使用方法:滚动时不能选择等等
cocos2dx 3.0版本号TableView拍生自ScrollView,经常使用来做滚动列表,有几种特殊使用方法,不知道大家用到过没 要求:1.滚动时不能选中TableCell,非滚动状态才干选中 ...
- QML Image得到的图片资源路径的详细信息
最近又开始了Qt5.在学习QML当地的资源总是越来越留念类似 " QML Image: Cannot open: qrc:///images/Blue hills.jpg "的错误 ...
- Asterisk 未来之路3.0_0005
原文:Asterisk 未来之路3.0_0005 第二章: Asterisk的架构 Asterisk 和其他众多传统的PBX是有区别的,拨号方案针对各种通道处理本质上采用同一种方式. 在传统的PB ...
- Mac OSX系统安装和配置Zend Server 6教程(2)
继上一节安装好Zend Server 6以后,我们需要修改配置文件.首先修改服务器监听端口.默认的情况下Zend Server 6安装以后的端口是10088.一般开发者使用的都是HTTP默认端口80. ...
- CSS边框阴影效果
ul { margin:5px 0 0 0; padding:0; list-style:none; width:300px; background:#f1f1f1; }li { border-lef ...
- gradle测试与线上打包
首先,第一反应理所当然的是profile : <?xml version="1.0" encoding="UTF-8"?> <beans xm ...
- 对TextView设置drawable,用setCompoundDrawables方法实现
在上一项目上需要对TextView在xml文件中设置的drawableLeft的图片进行更改,查询了资料好久也没有找到解决办法,如下代码所示: commentTV.setCompoundDrawabl ...