該問題從clone()方法開始引出数焊。
clone()是基類Object類中的一個protected方法胃夏。
對該方法做以下測試。
問題所在:https://segmentfault.com/q/1010000007236444
1. 在類A中調(diào)用類A實(shí)例a的clone()方法
public class A implements Cloneable {
public static void main(String[] args) throws CloneNotSupportedException {
A a = new A();
// 調(diào)用正確
A a2 = (A) a.clone();
}
}
以上調(diào)用成功昌跌,因?yàn)锳是object的子類,繼承了Object中的clone()方法照雁,所以可以直接調(diào)用蚕愤。
2. 在類B中調(diào)用類A實(shí)例a的clone()方法
public class B {
public static void main(String[] args) {
A a = new A();
// 調(diào)用失敗
a.clone();
}
}
錯誤信息:
以上調(diào)用出錯,A和B都是Object的子類饺蚊,都繼承了clone()方法萍诱,但不能在一個子類中調(diào)用另一個子類的protected方法。
如果需要在類B中實(shí)現(xiàn)對實(shí)例a的clone污呼,類A需要重寫clone方法裕坊,并且申明為public,如下:
類A:
public class A implements Cloneable {
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
類B:
public class B {
public static void main(String[] args) throws CloneNotSupportedException {
A a = new A();
// 調(diào)用成功
a.clone();
}
}
以上調(diào)用成功燕酷,因?yàn)轭怉重寫了clone方法籍凝,并且申明為public。
3. 提出問題苗缩,數(shù)組為什么可以直接調(diào)用clone()方法
public class ArrayClone {
public static void main(String[] args) {
int[] array = {1, 1, 4, 7};
// 調(diào)用成功
array.clone();
}
}
如果把a(bǔ)rray理解成為Object的子類饵蒂,那么該array應(yīng)該不能在類ArrayClone中調(diào)用clone()方法。但是可以調(diào)用成功酱讶。
此外:
章節(jié)1中退盯,直接在類A中調(diào)用實(shí)例a的clone()方法時,IDE明確指出clone()方法是protected的,智能提示上有個小鑰匙渊迁。
而在章節(jié)3中慰照,調(diào)用數(shù)組的clone()方法時,IDE提示該方法是public的琉朽,智能提示上有個打開的鎖毒租。
4. 提問
1. Java中是否有一個類對應(yīng)數(shù)組?數(shù)組在jvm中是一個怎樣的存在漓骚?
2. 數(shù)組的clone()方法是怎么實(shí)現(xiàn)的蝌衔?為什么可以直接調(diào)用?為什么是public的蝌蹂?
3. 數(shù)組的.length方法是怎么實(shí)現(xiàn)的噩斟?為什么IDE點(diǎn)不進(jìn)去源碼?
5. 參考
一些參考孤个,可能對可能不對的解釋剃允。
- 其實(shí)是有對應(yīng)的類的,但不是Java的類齐鲤,是JVM編譯的時候?qū)崿F(xiàn)的斥废。
- 這個類的命名,如int數(shù)組為[I给郊,如String數(shù)組為[Ljava.lang.String;牡肉,如A數(shù)組為[Ltest.cloneTest.A;。
- 用.getClass().getName()和.getClass().getInterfaces()即可知道該特殊類的類名和該類實(shí)現(xiàn)的接口淆九。
- 得到該類實(shí)現(xiàn)了Cloneable和Serializable接口统锤。和Object中寫明的Note that all arrays are considered to implement the interface Cloneable吻合。
- 猜測是Java編譯器允許的數(shù)組定義的語法糖炭庙,其實(shí)JVM會生成一個類饲窿,該類實(shí)現(xiàn)了Cloneable和Serializable接口,并且有一個public的clone()方法焕蹄,可以在其他類中直接調(diào)用逾雄。(其實(shí)沒有這個方法,可以通過.get.getMethods()進(jìn)行驗(yàn)證)
- 至于數(shù)組的length屬性腻脏,可能是直接保存在這個特殊的類的類頭部中了鸦泳,畢竟數(shù)組長度是不能修改的,直接保存著是完全符合邏輯的永品。