今天同事提出了一個問題: 將對象a 轉化為類型b,b 的classpath 是在配置文件中配置的,需要在運行中使用Class.forName 動態load進來,因為之前從來沒有想過類似的問題,所以懵掉了,然后迅速的查找資料,先將結果做下記錄,歡迎大家來討論一下。
想法一:
能否使用Class.forName的返回值(Class<?>)來進行類型轉換,代碼如下:
a o = new a();
(Class.forName("test.java.b"))o;
類型轉換基本上都是在compile的時候就確定了的,所以上述代碼是無法編譯通過的,使用這樣的方法是行不通的
想法二:
能否使用Class類中cast方法來進行類型轉換?代碼如下:
a o = new a();//比如a繼承於b,b中存在f()方法
Class.forName("test.java.cast.b").cast(a).f();//編譯不通過,找不到f方法
上述代碼中,cast方法是成功的,只是轉換之后的對象找不到f()方法,為什么會這樣呢?下面我們看一下cast的源碼
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException();
return (T) obj;
}
cast 把給定的obj 轉換為泛型T,而Class.forName 的返回值為Class<?>,也就是說T是?,沒有具體的類型,這樣的話cast的返回值為Object
上述代碼相當於
a o = new a();
Object obj = Class.forName("test.java.cast.b").cast(a);
obj.f();//出錯,因為Object中沒有f方法
事實證明兩個想法都是行不通的,最好的辦法還是放棄類型轉換,使用java的反射機制來訪問給定對象的成員。
