String 部分源码分析
发布时间:2020-12-14 06:13:00 所属栏目:百科 来源:网络整理
导读:String 无参数构造函数 /** * 底层存储字符串的目标字节数组, * Jdk 8 之前都是字符数组 private final char[] value; */ @Stable private final byte[] value; /** * 编码底层字节数组的字符集,支持 LATIN1、UTF16 */ private final byte coder; /** * 字
String
/** * 底层存储字符串的目标字节数组, * Jdk 8 之前都是字符数组 private final char[] value; */ @Stable private final byte[] value; /** * 编码底层字节数组的字符集,支持 LATIN1、UTF16 */ private final byte coder; /** * 字符串的哈希码值,默认为 0 */ private int hash; // Default to 0 /** * 创建一个空字符串 * created by ZXD at 18 Nov 2018 T 11:17:48 */ public String() { this.value = "".value; this.coder = "".coder; }
public String(byte[] bytes) { this(bytes,bytes.length); } 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[],Charset charset) { this(bytes,bytes.length,charset); } public String(byte bytes[],int length,Charset charset) { // 防御式编程,null 校验 if (charset == null) throw new NullPointerException("charset"); checkBoundsOffCount(offset,bytes.length); // 根据指定的字符集对字节数组进行编码 StringCoding.Result ret = StringCoding.decode(charset,bytes,length); this.value = ret.value; this.coder = ret.coder; } public String(byte bytes[],String charsetName) throws UnsupportedEncodingException { this(bytes,charsetName); } public String(byte bytes[],String charsetName) throws UnsupportedEncodingException { if (charsetName == null) throw new NullPointerException("charsetName"); checkBoundsOffCount(offset,bytes.length); // 根据指定的字符集对字节数组进行编码,编码名称错误时,抛出 UnsupportedEncodingException 异常 StringCoding.Result ret = StringCoding.decode(charsetName,length); this.value = ret.value; this.coder = ret.coder; }
public String(char value[]) { this(value,value.length,null); } public String(char value[],int count) { this(value,count,rangeCheck(value,count)); } private static Void rangeCheck(char[] value,int count) { // 字符串下标合法性校验 checkBoundsOffCount(offset,value.length); return null; } String(char[] value,int off,int len,Void sig) { // 特殊场景优化处理 if (len == 0) { this.value = "".value; this.coder = "".coder; return; } if (COMPACT_STRINGS) { // 如果启用压缩,则将字符数组压缩,字符集设置为 LATIN1 byte[] val = StringUTF16.compress(value,off,len); if (val != null) { this.value = val; this.coder = LATIN1; return; } } // 字符数组不压缩时,字符集设置为 UTF16 this.coder = UTF16; this.value = StringUTF16.toBytes(value,len); }
public boolean equals(Object anObject) { // 地址相等则直接返回 true if (this == anObject) { return true; } // 形参对象为字符串 if (anObject instanceof String) { String aString = (String)anObject; // 字符编码相同时才能做比较 if (coder() == aString.coder()) { return isLatin1() ? StringLatin1.equals(value,aString.value) : StringUTF16.equals(value,aString.value); } } return false; }
public int length() { return value.length >> coder(); } byte coder() { return COMPACT_STRINGS ? coder : UTF16; } @Native static final byte LATIN1 = 0; @Native static final byte UTF16 = 1; // Unicode字符集的抽象码位映射为16位长的整数
public boolean equalsIgnoreCase(String anotherString) { return (this == anotherString) ? true : (anotherString != null) // 形参字符串不为 null && (anotherString.length() == length()) // 两个字符串长度一致 && regionMatches(true,anotherString,length()); // 编码后的区域是否匹配 }
public String concat(String str) { int olen = str.length(); if (olen == 0) { return this; } // 字符集相同时,直接通过数组拷贝进行拼接 if (coder() == str.coder()) { byte[] val = this.value; byte[] oval = str.value; int len = val.length + oval.length; byte[] buf = Arrays.copyOf(val,len); System.arraycopy(oval,buf,val.length,oval.length); return new String(buf,coder); } int len = length(); // 使用 UTF16 编码计算目标字节数组长度,并将它们都拷贝进去。 byte[] buf = StringUTF16.newBytesFor(len + olen); getBytes(buf,UTF16); str.getBytes(buf,len,UTF16); return new String(buf,UTF16); }
public String substring(int beginIndex,int endIndex) { int length = length(); // 索引合法性检测 checkBoundsBeginEnd(beginIndex,endIndex,length); int subLen = endIndex - beginIndex; // 特殊场景优化处理,截取的子字符串就是目标字符串 if (beginIndex == 0 && endIndex == length) { return this; } return isLatin1() ? StringLatin1.newString(value,beginIndex,subLen) : StringUTF16.newString(value,subLen); } /** * 起始索引和结束索引不在 0到 length()-1 范围内,则抛出 IndexOutOfBoundsException 异常 * 结束索引大于起始索引,则抛出 IndexOutOfBoundsException 异常 */ static void checkBoundsBeginEnd(int begin,int end,int length) { if (begin < 0 || begin > end || end > length) { throw new StringIndexOutOfBoundsException( "begin " + begin + ",end " + end + ",length " + length); } }
public char charAt(int index) { if (isLatin1()) { return StringLatin1.charAt(value,index); } else { return StringUTF16.charAt(value,index); } } StringLatin1#charAt public static char charAt(byte[] value,int index) { if (index < 0 || index >= value.length) { throw new StringIndexOutOfBoundsException(index); } return (char)(value[index] & 0xff); }
public boolean contains(CharSequence s) { return indexOf(s.toString()) >= 0; }
public boolean isEmpty() { return value.length == 0; }
public String replace(char oldChar,char newChar) { if (oldChar != newChar) { String ret = isLatin1() ? StringLatin1.replace(value,oldChar,newChar) : StringUTF16.replace(value,newChar); if (ret != null) { return ret; } } return this; } public String replace(CharSequence target,CharSequence replacement) { // 需要查找的字符序列 String tgtStr = target.toString(); // 需要替换的字符序列 String replStr = replacement.toString(); // 如果要查找的字符序列没有在目标字符串中,则返回其本身 int j = indexOf(tgtStr); if (j < 0) { return this; } // 查找字符序列的长度 int tgtLen = tgtStr.length(); int tgtLen1 = Math.max(tgtLen,1); // 当期字符串的长度 int thisLen = length(); int newLenHint = thisLen - tgtLen + replStr.length(); if (newLenHint < 0) { throw new OutOfMemoryError(); } StringBuilder sb = new StringBuilder(newLenHint); int i = 0; // 在 StringBuilder 指定的索引处追加字符串,并重新获取要查找的子字符串索引进行循环替换。 do { sb.append(this,i,j).append(replStr); i = j + tgtLen; } while (j < thisLen && (j = indexOf(tgtStr,j + tgtLen1)) > 0); return sb.append(this,thisLen).toString(); }
public String replaceAll(String regex,String replacement) { return Pattern.compile(regex).matcher(this).replaceAll(replacement); }
public String replaceFirst(String regex,String replacement) { return Pattern.compile(regex).matcher(this).replaceFirst(replacement); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |