String类源码分析
1、String类注释说明
/**
* The {@code String} class represents character strings. All
* string literals in Java programs, such as {@code "abc"}, are
* implemented as instances of this class.
* <p>
* Strings are constant; their values cannot be changed after they
* are created. String buffers support mutable strings.
*/
注释说明String是不变的类,即String类的值一旦被生成后就不能被改变了。
2、String类声明
public final class String implements java.io.Serializable, Comparable<String>, CharSequence
final关键字修饰String类表示String类不可以被其他类继承。
3、String类的属性
/** The value is used for character storage. */
private final char value[]; // final关键字修饰属性,可以看出String对象确实是不可改变的 /** Cache the hash code for the string */
private int hash; // Default to 0 /** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L; /**
* Class String is special cased within the Serialization Stream Protocol.
*
* A String instance is written into an ObjectOutputStream according to
* <a href="{@docRoot}/../platform/serialization/spec/output.html">
* Object Serialization Specification, Section 6.2, "Stream Elements"</a>
*/
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
4、String类构造方法
// 无参构造方法一般不用,因为值为空
public String() {
this.value = "".value;
} public String(String original) {
this.value = original.value;
this.hash = original.hash;
} public String(char value[]) {
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) {
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);
} public String(int[] codePoints, int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count <= 0) {
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
if (offset <= codePoints.length) {
this.value = "".value;
return;
}
}
// Note: offset or count might be near -1>>>1.
if (offset > codePoints.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
} final int end = offset + count; // Pass 1: Compute precise size of char[]
int n = count;
for (int i = offset; i < end; i++) {
int c = codePoints[i];
if (Character.isBmpCodePoint(c))
continue;
else if (Character.isValidCodePoint(c))
n++;
else throw new IllegalArgumentException(Integer.toString(c));
} // Pass 2: Allocate and fill in char[]
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;
} /* Common private utility method used to bounds check the byte array
* and requested offset & length values used by the String(byte[],..)
* constructors.
*/
private static void checkBounds(byte[] bytes, int offset, int length) {
if (length < 0)
throw new StringIndexOutOfBoundsException(length);
if (offset < 0)
throw new StringIndexOutOfBoundsException(offset);
if (offset > bytes.length - length)
throw new StringIndexOutOfBoundsException(offset + length);
} public String(byte bytes[], int offset, int length, String charsetName)
throws UnsupportedEncodingException {
if (charsetName == null)
throw new NullPointerException("charsetName");
checkBounds(bytes, offset, length);
this.value = StringCoding.decode(charsetName, bytes, offset, length);
} public String(byte bytes[], int offset, int length, Charset charset) {
if (charset == null)
throw new NullPointerException("charset");
checkBounds(bytes, offset, length);
this.value = StringCoding.decode(charset, bytes, offset, length);
} public String(byte bytes[], String charsetName)
throws UnsupportedEncodingException {
this(bytes, 0, bytes.length, charsetName);
} public String(byte bytes[], Charset charset) {
this(bytes, 0, bytes.length, charset);
} public String(byte bytes[], int offset, int length) {
checkBounds(bytes, offset, length);
this.value = StringCoding.decode(bytes, offset, length);
} public String(byte bytes[]) {
this(bytes, 0, bytes.length);
} public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
} public String(StringBuilder builder) {
this.value = Arrays.copyOf(builder.getValue(), builder.length());
} String(char[] value, boolean share) {
// assert share : "unshared not supported";
this.value = value;
}
5、String类常用方法
// 得到字符串长度,即字符数组value的大小
public int length() {
return value.length;
} // 判断字符串是否为空
public boolean isEmpty() {
return value.length == 0;
} // 得到索引位置的字符
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
} // 判断两个字符串是否相等,equals是Object类的方法,String覆写了该方法
public boolean equals(Object anObject) {
if (this == anObject) {
return 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;
} // 字符串比较操作,compareTo是Object类的方法,String覆写了该方法
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;
} // hashCode是Object类的方法,String类覆写了该方法
public int hashCode() {
int h = hash;
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 boolean startsWith(String prefix, int toffset) {
char ta[] = value;
int to = toffset;
char pa[] = prefix.value;
int po = 0;
int pc = prefix.value.length;
// Note: toffset might be near -1>>>1.
if ((toffset < 0) || (toffset > value.length - pc)) {
return false;
}
while (--pc >= 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}
// 重载上一个方法
public boolean startsWith(String prefix) {
return startsWith(prefix, 0);
}
// 判断字符串是否以另一个字符串结尾
public boolean endsWith(String suffix) {
return startsWith(suffix, value.length - suffix.value.length);
} // 得到子字符串
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 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);
} // 判断字符串是否包含某个字符串
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
} // 将其他类型数据转换为字符串的操作
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
public static String valueOf(char data[]) {
return new String(data);
}
public static String valueOf(char data[], int offset, int count) {
return new String(data, offset, count);
}
public static String copyValueOf(char data[], int offset, int count) {
return new String(data, offset, count);
}
public static String copyValueOf(char data[]) {
return new String(data);
}
public static String valueOf(boolean b) {
return b ? "true" : "false";
}
public static String valueOf(char c) {
char data[] = {c};
return new String(data, true);
}
public static String valueOf(int i) {
return Integer.toString(i);
}
public static String valueOf(long l) {
return Long.toString(l);
}
public static String valueOf(float f) {
return Float.toString(f);
}
public static String valueOf(double d) {
return Double.toString(d);
} // 本地方法,将字符串对象放入字符串常量池
public native String intern();
String类源码分析的更多相关文章
- String 类源码分析
String 源码分析 String 类代表字符序列,Java 中所有的字符串字面量都作为此类的实例. String 对象是不可变的,它们的值在创建之后就不能改变,因此 String 是线程安全的. ...
- String类源码分析(JDK1.7)
以下学习根据JDK1.7String类源代码做注释 public final class String implements java.io.Serializable, Comparable<S ...
- List 接口以及实现类和相关类源码分析
List 接口以及实现类和相关类源码分析 List接口分析 接口描述 用户可以对列表进行随机的读取(get),插入(add),删除(remove),修改(set),也可批量增加(addAll),删除( ...
- Cocos2d-X3.0 刨根问底(六)----- 调度器Scheduler类源码分析
上一章,我们分析Node类的源码,在Node类里面耦合了一个 Scheduler 类的对象,这章我们就来剖析Cocos2d-x的调度器 Scheduler 类的源码,从源码中去了解它的实现与应用方法. ...
- Java Properties类源码分析
一.Properties类介绍 java.util.Properties继承自java.util.Hashtable,从jdk1.1版本开始,Properties的实现基本上就没有什么大的变动.从ht ...
- java中List接口的实现类 ArrayList,LinkedList,Vector 的区别 list实现类源码分析
java面试中经常被问到list常用的类以及内部实现机制,平时开发也经常用到list集合类,因此做一个源码级别的分析和比较之间的差异. 首先看一下List接口的的继承关系: list接口继承Colle ...
- Java并发编程笔记之Unsafe类和LockSupport类源码分析
一.Unsafe类的源码分析 JDK的rt.jar包中的Unsafe类提供了硬件级别的原子操作,Unsafe里面的方法都是native方法,通过使用JNI的方式来访问本地C++实现库. rt.jar ...
- Cocos2d-X3.0 刨根问底(三)----- Director类源码分析
上一章我们完整的跟了一遍HelloWorld的源码,了解了Cocos2d-x的启动流程.其中Director这个类贯穿了整个Application程序,这章随小鱼一起把这个类分析透彻. 小鱼的阅读源码 ...
- java.lang.String 类源码解读
String类定义实现了java.io.Serializable, Comparable<String>, CharSequence 三个接口:并且为final修饰. public fin ...
随机推荐
- NLP 开源形近字算法补完计划(完结篇)
前言 所有的故事都有开始,也终将结束. 本文将作为 NLP 汉字相似度的完结篇,为该系列画上一个句号. 起-NLP 中文形近字相似度计算思路 承-中文形近字相似度算法实现,为汉字 NLP 尽一点绵薄之 ...
- shell常用集锦
该文整理一些常用的shell用法,及语法,并非介绍如何使用 变量 变量可分为两类:环境变量ENV(全局)和局部变量. bash环境变量 变量名 含义 _= 上一条命令的最后一个参数 BASH_VERS ...
- 关于前端项目cookie的获取
最近项目在做切换,2.0要升级到3.0,遇到跨域问题,使用的是nginx 进行对端口拦截请求其他地址,另外有的服务还要登录权限,之前没看到有这个,后来加上获取cookie的请求 var v3_toke ...
- git新手配置(ios环境)
ios环境,初步了解git是个什么东西,使用过svn相关软件最佳,否则可以先补一下git的相关概念和用处,相关教程:https://www.liaoxuefeng.com/wiki/896043488 ...
- CF1610F F. Mashtali: a Space Oddysey
我们首先发现有如下性质: 我们不妨先随机定向边,那么我们发现无论我们如何翻转边. 都会对其两端的点,造成 \(2 / 4\) 的影响,所以我们发现如果一个点其和他相连的所有边权和为偶数,则我们不能调整 ...
- Codeforces 1368E - Ski Accidents(构造+思维)
Codeforces 题面传送门 & 洛谷题面传送门 神仙构造题(不过可能我构造太烂了?) 首先考虑这个奇奇怪怪的 \(\dfrac{4}{7}\),以及这个每个点出度最多为 \(2\) 的条 ...
- 洛谷 P5527 - [Ynoi2012] NOIP2016 人生巅峰(抽屉原理+bitset 优化背包)
洛谷题面传送门 一道挺有意思的题,想到了某一步就很简单,想不到就很毒瘤( 首先看到这样的设问我们显然可以想到背包,具体来说题目等价于对于每个满足 \(i\in[l,r]\) 的 \(a_i\) 赋上一 ...
- mVISTA 多序列比对叶绿体基因组
mVISTA可对2个或者多个DNA序列进行比较,可以对比对结果进行可视化. 详情请大力戳这里 0 输入文件说明 mVISTA 需要输入的文件有如下几类 必须文件 邮箱 fasta格式序列文件(或者GE ...
- du命令之计算文件大小
在linux中,常用du命令来计算文件或目录的大小 名称: du - 计算每个文件的磁盘用量,目录则取总用量. 用法: du [选项]... [文件]... 常用选项 -a, --all 输出所有文件 ...
- 作业帮上万个 CronJob 和在线业务混部,如何解决弱隔离问题并进一步提升资源利用率?
作者 吕亚霖,作业帮基础架构 - 架构研发团队负责人.负责技术中台和基础架构工作.在作业帮期间主导了云原生架构演进.推动实施容器化改造.服务治理.GO 微服务框架.DevOps 的落地实践. 别路,作 ...