目录
简介
string是java中的字符串类
/**
*
* <p>String类代表字符串。java程序中的所有字符串常量,例如"abc",是这个类的实例。
*
* <p>字符串是常量,它们的值不能在被创造后改变。字符串缓冲区支持可变的字符串。
* 字符串对象是不可变的,因为它们能被共享。例如:
*
* <blockquote><pre>
* String str = "abc";
* </pre></blockquote><p>
* 等价于
* <blockquote><pre>
* char data[] = {'a', 'b', 'c'};
* String str = new String(data);
* </pre></blockquote><p>
* 下面有更多的字符串如何被使用的例子:
* <blockquote><pre>
* System.out.println("abc");
* String cde = "cde";
* System.out.println("abc" + cde);
* String c = "abc".substring(2,3);
* String d = cde.substring(1, 2);
* </pre></blockquote>
*
* <p>String类包含了各种方法,包括检查序列中单独的字符,比较字符串,
* 查询字符串,抽取子序列,创造一个所有字符变为大小或小写的字符串副本。
* 大小写映射基于Character类指定的Unicode的标准版本。
*
* <p>java语言为字符串连接符号(+)和其他对象转为字符串提供了特殊的支持。
* 字符串连接由StringBuilder或者StringBuffer类和它们的方法来实现。
* 字符串转换由方法toString来实现,这个方法被Ojbect定义,并且被java中所有的类继承,可以看java语言规范。
*
* <p>除非另有说明,传入这个类的构造器或方法一个null参数会导致抛出NullPointerException
*
* <p>字符串代表UTF-16格式的字符串,其中补充字符有代理对标识(看Character类的Unicode Character Representation)。
* 索引值对应char的代码单元,所以一个补充字符在String中占用两个位置(两个代码单元)。
* 而正常字符和补充字符都对应一个代码点,但可能有1-2个代码单元。
* 就是说每个字符可能对应1-2个char,有的字符可能在char数组中占据两个位置。
*
* <p>String类提供了处理Unicode代码点和处理Unicode代码单元的方法。
*
* @author Lee Boynton
* @author Arthur van Hoff
* @author Martin Buchholz
* @author Ulf Zibis
* @see java.lang.Object#toString()
* @see java.lang.StringBuffer
* @see java.lang.StringBuilder
* @see java.nio.charset.Charset
* @since JDK1.0
*/
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
字段
/** 用来保存字符的值 ,注意:这是一个char序列,而且是final的,不可更改*/
private final char value[];
/** 缓存字符串的hash码*/
private int hash; // 默认为0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
/**
* 类字符串在序列化流协议中使用特殊的大小写。
* 一个字符串实例根据类的序列化规范来写入ObjectOutputStream。
*/
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
创建string
构造器
参数为string,char
/**
* 初始化一个新建的String对象,从而它代表一个空的字符串序列。
* 注意这个构造器是不需要的,因为字符串是不可变的。
*/
public String() {
this.value = "".value;
}
/**
* 初始化一个新建的String对象,从而它代表与参数相同的字符串序列。
* 换言而之,新建的字符串是参数字符串的拷贝。
* 除非需要一个original的独一无二的拷贝,不需要使用这个构造器,因为字符串是不可更改的
*
* @param original
* A {@code String}
*/
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
/**
* 分配一个新字符串,从而它代表的字符串序列包含了字符序列参数。
* 字符序列的内容被拷贝了。
* 之后对参数字符序列的修改不影响新建的字符串。
*
* @param value
* The initial value of the string
*/
public String(char value[]) {
//value值为一个复制的新数组。
this.value = Arrays.copyOf(value, value.length);
}
/**
* 分配一个新的String,它包含了参数字符数组的一个子数组。
* offset参数是子数组的第一个字符的位置,count参数指定了子数组的长度。
* 子数组的内容被复制。之后对字符数组的修改不影响新建的字符串。
*
* @param value
* Array that is the source of characters
*
* @param offset
* The initial offset
*
* @param count
* The length
*
* @throws IndexOutOfBoundsException
* If the {@code offset} and {@code count} arguments index
* characters outside the bounds of the {@code value} array
*/
public String(char value[], int offset, int count) {
if (offset < 0) {
//排除offset<0
throw new StringIndexOutOfBoundsException(offset);
}
if (count <= 0) {
if (count < 0) {
//如果count<0,报错
throw new StringIndexOutOfBoundsException(count);
}
if (offset <= value.length) {
//如果count==0而且offset<=value.length
//建一个空字符串
this.value = "".value;
return;
}
}
// Note: offset or count might be near -1>>>1.
if (offset > value.length - count) {
//如果offset+count>value.length,报错
throw new StringIndexOutOfBoundsException(offset + count);
}
//将value数组的一部分复制到一个新的char数组
this.value = Arrays.copyOfRange(value, offset, offset+count);
}
参数为代码点
/**
* 分配一个新的String,包含从一个Unicode代码点数组参数的子数组的字符。
* offset参数是子数组的第一个代码点的位置,count参数指定了子数组的长度。
* 子数组的内容被转换为char,之后对int数组的修改不影响新建的string
*
* @param codePoints Unicode代码点来源数组
*
* @param offset
* The initial offset
*
* @param count
* The length
*
* @throws IllegalArgumentException
* If any invalid Unicode code point is found in {@code
* codePoints}
*
* @throws IndexOutOfBoundsException
* If the {@code offset} and {@code count} arguments index
* characters outside the bounds of the {@code codePoints} array
*
* @since 1.5
*/
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) {
//如果count<=0而且offset处于正常返回,返回空字符串
this.value = "".value;
return;
}
}
// 注意: offset 或 count 可能接近Integer.max
if (offset > codePoints.length - count) {
//如果offset+count>length
throw new StringIndexOutOfBoundsException(offset + count);
}
final int end = offset + count;
// Pass 1: 计算char数组的准确大小
int n = count; //初始大小为count
for (int i = offset; i < end; i++) {
int c = codePoints[i];
if (Character.isBmpCodePoint(c))
//如果代码点是BMP代码点,就为一个代码单元,大小不变
continue;
else if (Character.isValidCodePoint(c))
//如果不是BMP,但是是合法的代码点,就为两个代码单元,大小+1
n++;
//都不是的话,说明代码点是非法的
else throw new IllegalArgumentException(Integer.toString(c));
}
// Pass 2: 分配并填充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))
//如果c是BMP代码点,直接填充
v[j] = (char)c;
else
//否则j为c的高代理代码单元,j++为低代理代码单元
Character.toSurrogates(c, v, j++);
}
//最后value为填充完的char数组
this.value = v;
}
参数为byte
/**
* Allocates a new {@code String} constructed from a subarray of an array
* of 8-bit integer values.
*
* <p> The {@code offset} argument is the index of the first byte of the
* subarray, and the {@code count} argument specifies the length of the
* subarray.
*
* <p> Each {@code byte} in the subarray is converted to a {@code char} as
* specified in the method above.
*
* @deprecated This method does not properly convert bytes into characters.
* As of JDK 1.1, the preferred way to do this is via the
* {@code String} constructors that take a {@link
* java.nio.charset.Charset}, charset name, or that use the platform's
* default charset.
*
* @param ascii
* The bytes to be converted to characters
*
* @param hibyte
* The top 8 bits of each 16-bit Unicode code unit
*
* @param offset
* The initial offset
* @param count
* The length
*
* @throws IndexOutOfBoundsException
* If the {@code offset} or {@code count} argument is invalid
*
* @see #String(byte[], int)
* @see #String(byte[], int, int, java.lang.String)
* @see #String(byte[], int, int, java.nio.charset.Charset)
* @see #String(byte[], int, int)
* @see #String(byte[], java.lang.String)
* @see #String(byte[], java.nio.charset.Charset)
* @see #String(byte[])
*/
@Deprecated
public String(byte ascii[], int hibyte, int offset, int count) {
checkBounds(ascii, offset, count);
char value[] = new char[count];
if (hibyte == 0) {
for (int i = count; i-- > 0;) {
value[i] = (char)(ascii[i + offset] & 0xff);
}
} else {
hibyte <<= 8;
for (int i = count; i-- > 0;) {
value[i] = (char)(hibyte | (ascii[i + offset] & 0xff));
}
}
this.value = value;
}
/**
* Allocates a new {@code String} containing characters constructed from
* an array of 8-bit integer values. Each character &