一:背景
在查JDK時,偶然發現Object類中的clone()方法是protected的,有點感覺怪怪的,在網上搜索了半天,才豁然開朗,現總結如下。
二:我們以前所認識的“protected”
我們以前認識的protected多用在修飾實例變量和類變量,方法之上,限定訪問範圍,表示可以同時被在同一個包中的類,和子類所訪問。但在瞭解了clone()這個方法後(這個方法在Object類中爲protected)發現不全然是這樣,下面用代碼說明。
三:揭開protected更深的面紗
我們先看以下代碼:
package com.xd.one;
public class T1 {
public static void main(String[] args) throws CloneNotSupportedException {
new T2().clone();
}
}
class T2{
}
編譯下面代碼時發現除了錯誤,報的是The method clone() from the type Object is not visible,意思就是T1你不能訪問T2的clone()方法,爲什麼呢?就是protected在搗鬼,因爲T1,T2都是Object的子類,所以有這麼一條規定(此規定存在問題,後面逐步完善),不能在一個子類中訪問另一個子類的protected方法(從相同父類繼承而來).
我們再看一個代碼:
package com.xd.one;
public class T1 {
public static void main(String[] args) throws CloneNotSupportedException {
new T2().clone();
}
}
class T2{
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
我們發現,當在T2中主動去覆蓋了Object的方法clone後,在T1中可以訪問了,所以綜上兩種情況,得出最終的一條結論(用clone()方法舉例):
與基類不在同一個包中的子類(Object與T1不在同一個包中),只能訪問自身從基類繼承而來的受保護成員,而不能訪問另一個基類實例從父類繼承而沒有重寫的受保護成員(當然,前提是這兩個子類在同一個包中,並且另一個子類覆蓋的clone()方法沒有改變訪問權限,既還是protected,如果覆蓋時從protected升爲了public,此時就不需要在一個包中這個前提了!)。