1. 為什麼Python list的索引從0開始
如果你的l是如此定義的
List l=new ArrayList();
那麼拋出此異常是非常正確的!因為java到源碼如下:
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
//你的程序就符合index>size,所以就拋出IndexOutOfBoundsException
ensureCapacity(size+1); // Increments modCount!!
System.array(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
2. 如何查看java源碼中的native方法源碼
下載JDK源代碼啊,openJDK上有完整的JDK源代碼,JDK源代碼由C++、Java、C、匯編 這四種語言組成。JVM主體是C++寫的,JNI部分是C,工具類是Java寫的,JVM里混有匯編代碼。路徑:openjdk-7-fcs-src-b147\jdk\src\share\native\java\lang\System.c 找到這個
/* Only register the performance-critical methods */
static JNINativeMethod methods[] = {
{"currentTimeMillis", "()J", (void *)&JVM_CurrentTimeMillis},
{"nanoTime", "()J", (void *)&JVM_NanoTime},
{"array", "(" OBJ "I" OBJ "II)V", (void *)&JVM_ArrayCopy},
};
方法的實現應該在JVM部分,路徑openjdk-7-fcs-src-b147\hotspot\src\share,不同的操作系統實現不一樣,應該是在對應的操作系統的包下
3. String類源碼筆記(一):成員變數和構造器
String類表示字元串,所有類似"abc"形式的字元串(或魔法字元串)都被看作是這個類的實例。String是不可變的,當一個字元串在常量池中被創建時,他的值就不會被改變。
所在路徑:javalangString.java
為了保證String類是一個不可變類,String類的成員變數多為私有和不可變的。
其中serialPersistentFields在序列化時使用:
JDK8的String類一共有16個構造器,其中兩個是@Deprecated,一個是私有構造器,剩下的13個是可以調用的。
無參構造器直接將""的value賦值給當前類的value。""的value是一個空的char[],其length為0。調用使用了無參構造器的String對象的isEmpty()方法會得到true,調用length()方法會得到0,判斷其==null會得到false。
入參為String對象時,構造器會對其進行直接取值。
入參為字元串數組時,構造器調用的是Arrays.Of()方法。
其中Arrays.Of()方法是為了將入參的字元串序列深拷貝到this.valuie中,他的源碼為:
其中System.array()方法的源碼為:
這個方法支持直接傳入想要生成的String的母串,通過偏移量和有效長度找出需要賦值給this.value的部分,然後調用Arrays.OfRange()方法進行深拷貝。
當需要將一個Unicode編碼序列轉換為String時,可以使用以下構造器:
當需要將一個bytes[]轉換為String時,可以使用以下構造器:
此外,還有一些將上述構造器進一步封裝的構造器,其本質都是簡化入參。另外,String類的構造器同樣支持傳入StringBuffer和StringBuilder。如果傳入的是StringBuffer,構造器會為其加鎖。如果傳入的是StringBuilder則不會加鎖。
事實上,StringBuffer和StringBuilder的toString()方法調用的也是String類的構造器,他們最終的底層實現都是Arrays.Of()。
最後,String類還提供了一個保護類型的構造方法。該方法相比入參為char[]的構造器多了一個share參數,這個參數並沒有實際作用,只是用來和其他構造器進行區分。當String類內部調用該構造器時:
該構造器不能對外暴露的原因是需要保持String類的不可變性。