只有一個參數的;
String str = new String("ABCD");
System.out.println("str="+str.substring(1));
進入substring()
public String substring(int beginIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
int subLen = length() - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
if (beginIndex == 0) {
return this;
}
return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)
: StringUTF16.newString(value, beginIndex, subLen);
}
分析:
- 當 beginIndex < 0或者 beginIndex > length的時候,直接拋出越界異常;
- 當 beginIndex 就是0 的時候,返回原字符串;
- 最后判斷是 isLatin1是否滿足,進入StringLatin1/StringUTF16;
進入StringLatin1.newString
public static String newString(byte[] val, int index, int len) {
return new String(Arrays.copyOfRange(val, index, index + len),
LATIN1);
}
分析:
- byte[] val : 也就是str的構成數組,{A,B,C,D};
- int index:beginIndex = 1;
- int len :subLen = 4 -1 = 3;
再調用 Arrays.copyOfRange
public static byte[] copyOfRange(byte[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
byte[] copy = new byte[newLength];
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}
分析:
- byte[] original:還是{A,B,C,D};
- int from : index = 1;
- int to :index + len = 1 + 3 = 4 (實際就是str的長度);
- 該方法定義了一個新的數組,長度為:length - beginIndex = 3;
最后調用:
System.arraycopy
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
分析:
- 參數1,src ,源數組 ,傳入 original,{A,B,C,D};
- 參數2 ,srcPos 源數組的開始位置,傳入 beginIndex = 1;
- 參數3, dest ,目標數組,傳入是一個空的 length 為 3的數組;
- 參數4,destPos 目標數組的開始位置,傳入 0;
- 參數5,length 需要copy元素的數量,本次調用,傳遞的是 length - beginIndex = 3(經過最小值判斷,仍然等價)
- 結果:
- copy[0] = original[1];
- copy[1] = original[2];
- copy[2] = original[3];
綜上,str.subString(i) 實際上是
- 將 str 轉成數組 array01,賦值給一個為新的數組 array02,并且array02.length = str.length - i;
- 賦值過程為:array02[0] = array01[i](直到i = array01.length)
- array02轉換新的String,并返回;
得出結論:subString(i)返回值是 str的索引位置i,到最大索引(兩個索引都包括)