1.定义
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
- final类,不可被继承
- 实现java.io.Serializable接口,可被序列化
- 实现Comparable<String>,可以进行比较
- 实现CharSequence,只读有序序列
2.变量
/**
* 即 value[] 是用来存储字符的,存储之后不能被修改
* 使用 @Stable 来表示信任 value[] 中内容,因为value[] 不会为null
*/
@Stable
private final byte[] value;
/**
* 用来对 value[] 中的byte 进行编码,支持的编码有
* LATIN1 (ISO-8859-1) 和 UTF16
*/
private final byte coder;
/** 缓存字符串的哈希 */
private int hash; // Default to 0
/** 序列化Id 标识 */
private static final long serialVersionUID = -6849794470754667710L;
/**
* 如果禁用字符压缩,则value[]中默认是使用UTF-16进行编码
* 在对于优化JIT编译器时,实例化的值通常是不透明的。
* 因此在行为敏感的地方,首先检查 静态变量 COMPACT_STRINGS,然后在检查 coder
* COMPACT_STRINGS 字段的实际值由JVM注入
*/
static final boolean COMPACT_STRINGS;
static {
COMPACT_STRINGS = true;
}
/**
* 类字符串在序列化流协议中是特殊情况
*/
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
3.构造方法
/**
* 1.无参构造,将 “” 赋值给 value
*/
public String() {
this.value = "".value;
this.coder = "".coder;
}
/**
* 2.有参构造,将 original 的值赋给 新的 String
*/
@HotSpotIntrinsicCandidate
public String(String original) {
this.value = original.value;
this.coder = original.coder;
this.hash = original.hash;
}
/**
* 3.有参构造,将 value[] 的值赋给 新的 String
*/
public String(char value[]) {
this(value, 0, value.length, null); // this 调用方法如下
}
/**
* 4.有参构造,作上面3的补充,将 value[] 的值赋给 新的 String,例子如下:
* char[] test = {'1','2','3','4','5','6','7','8','9','0'};
* String b = new String(test,2,3); // "345"
*/
public String(char value[], int offset, int count) {
this(value, offset, count, rangeCheck(value, offset, count));
}
/**
* 检查是否存在越界操作
*/
private static Void rangeCheck(char[] value, int offset, int count) {
checkBoundsOffCount(offset, count, value.length);
return null;
}
/**
* 将 char value[] 的转存为 bytes[]
*/
String(char[] value, int off, int len, Void sig) {
if (len == 0) {
this.value = "".value;
this.coder = "".coder;
return;
}
if (COMPACT_STRINGS) {
byte[] val = StringUTF16.compress(value, off, len);
if (val != null) {
this.value = val;
this.coder = LATIN1;
return;
}
}
this.coder = UTF16;
this.value = StringUTF16.toBytes(value, off, len);
}
/**
* bytes[] 构造 ,charsetName 为字符集
* @throws UnsupportedEncodingException 如果不支持该字符集,则抛出异常
* @throws IndexOutOfBoundsException 如果offset或者 length存在问题则抛异常
*/
public String(byte bytes[], int offset, int length, String charsetName)
throws UnsupportedEncodingException {
if (charsetName == null)
throw new NullPointerException("charsetName");
checkBoundsOffCount(offset, length, bytes.length);
StringCoding.Result ret =
StringCoding.decode(charsetName, bytes, offset, length);
this.value = ret.value;
this.coder = ret.coder;
}
/**
* bytes[] 其他构造
*/
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) {
checkBoundsOffCount(offset, length, bytes.length);
StringCoding.Result ret = StringCoding.decode(bytes, offset, length);
this.value = ret.value;
this.coder = ret.coder;
}
public String(byte[] bytes) {
this(bytes, 0, bytes.length);
}
// StringBuffer构造
public String(StringBuffer buffer) {
this(buffer.toString());
}
// StringBuilder构造
public String(StringBuilder builder) {
this(builder, null);
}
4.常用方法
- 长度
public int length() {
return value.length >> coder();
}
byte coder() {
// 其中 UTF16 = 1 coder = 0
return COMPACT_STRINGS ? coder : UTF16;
}
- 判空
public boolean isEmpty() {
return value.length == 0;
}
- charAt
// 返回字符串中的第index位置的值
public char charAt(int index) {
if (isLatin1()) {
return StringLatin1.charAt(value, index);
} else {
return StringUTF16.charAt(value, index);
}
}
5.不常用方法
- codePointAt
// 返回字符串中的index 位置处的Unicode码
public int codePointAt(int index) {
if (isLatin1()) {
checkIndex(index, value.length);
return value[index] & 0xff;
}
int length = value.length >> 1;
checkIndex(index, length);
return StringUTF16.codePointAt(value, index, length);
}
StringUTF16.codePointAt()
public static int codePointAt(byte[] value, int index, int end) {
return codePointAt(value, index, end, false /* unchecked */);
}
private static int codePointAt(byte[] value, int index, int end, boolean checked) {
assert index < end;
if (checked) {
checkIndex(index, value);
}
char c1 = getChar(value, index);
if (Character.isHighSurrogate(c1) && ++index < end) {
if (checked) {
checkIndex(index, value);
}
char c2 = getChar(value, index);
if (Character.isLowSurrogate(c2)) {
return Character.toCodePoint(c1, c2);
}
}
return c1;
}
网友评论