原文地址:http://leihuang.org/2014/11/14/getClass-method/
首先看一段代碼:
import java.util.Date;
public class Test extends Date{
public static void main(String[] args) {
new Test().test();
}
public void test(){
System.out.println(super.getClass().getName());
}
}
上面這段代碼的輸出爲:Test
可能你會奇怪爲什麼輸出的是Test,而不是Date呢?我明明是調用的super.getClass()啊。我們先不急,先來了解一下getClass()方法的機制是什麼。下面時getClass()在Object類中實現的源碼。
Returns the runtime classof this Object. The returned Class object is the object that is locked by static synchronized methods of the represented class. The actual result type is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment: Number n = 0; Class<? extends Number> c = n.getClass(); Returns: The Class object that represents the runtime class of this object.
public final native Class<?> More ...getClass();
從上面我們可以得知兩點:
- getClass()方法: 返回此 Object 的運行時類。返回的 Class 對象是由所表示類的 static synchronized 方法鎖定的對象。
- getClass()時final方法,子類無法重寫。
第一點我們可以得出:
什麼是運行時類,運行時類是Object的一個實例,注意了,關鍵來了,他返回的不是Object.class,他返回的是運行時類,就是虛擬機中是誰在運行就是誰,如果你new Date(),Date當然是運行時類,而不是Object,否則所有類的getClass()方法都返回了Object.class 了。
根據上一段解釋,Date是Object的子類,Date.getClass()返回的肯定是Date.class,
同樣的Test繼承Date,假如有一個屬於Date的getClass()他返回的也不可能是Date.class,因爲當new Test()後,Test是一個運行時類,只不過他擁有Date的資源結構。所以誰被實例化,誰就是一個運行時類。
第二點我們可以得出
上面我們討論了,Object中getClass()方法返回的是運行時類對象,誰被實例化,getClass()就得到誰。但那只是Object中的getClass()方法而已,而我們時調用的Date.getClass(),or Test.getClass().
這裏就涉及到getClass()方法在Object中時final方法了,因此子類是無法重寫getClass方法的,所以不管是Date.getClass()還是Test.getClass(),其實調用的都是Object中的getClass()方法,這樣就保證了會遵循第一點。
如果想要從Test中得到Date.class,可以用Test.getClass().getSuperClass();
2014-11-14 12:06:54
Brave,Happy,Thanksgiving !