從語言學的角度來看,你寫的東西沒有任何意義。 Foo
是一種類型,並且類型不是變量,不能出現在作業的LHS上。您不能將類型視爲Java中的值...該語言不允許它。
,你可以得到什麼,你正在嘗試做的最接近的是這樣的:
Class fooClass;
if (loadFoo1) {
fooClass = Class.forName("some.pkg.Foo1");
} else {
fooClass = Class.forName("some.pkg.Foo2");
}
Foo foo = (Foo) fooClass.newInstance(); // using the no-args constructor
(我已經離開了異常處理...)
注意fooClass
會是Class
類的一個實例,它提供用於反射執行操作的運行時句柄。我們實際上並沒有分配類型。我們以有限的方式分配一個「表示」類型的對象。
無論其 ...如果你不這樣做需要使用動態加載,你不應該使用它。換句話說,如果你正試圖解決的根本問題是創建類的實例,可能靜態加載,那麼最好使用工廠模式;例如,請參閱@ andersoj的答案。
UPDATE
我只是想出了什麼你可能想在這裏做。也就是說,您正試圖找出一種方法來在不同的靜態方法(即Foo1.method()
和Foo2.method()
)之間進行選擇,而無需在進行調用的位置明確指定類。
同樣,你正在嘗試做的,根本不會在Java中工作:
- 你不能聲明一個接口的靜態方法。
- 您不能通過接口在實現類中調用靜態方法。
- 靜態方法調用不在Java中「調度」。它們是靜態綁定的。
有一種方法可以使用反射來做類似這樣的事情;例如
Class fooClass;
// Load one or other of the classes as above.
Method m = fooClass.getDeclaredMethod("method");
Integer res = (Integer) m.invoke(null);
(和以前一樣,我已經離開了異常處理)
再次,你會好得多這樣做,而不訴諸動態加載和思考。簡單的方法是在一些公用事業類來創建這樣一個輔助方法:
public static int method() {
return useFoo1 ? Foo1.method() : Foo2.method();
}
更妙的是,這樣做的OO方式:在Foo
接口作爲實例方法聲明method
,創建注入了一單或例如Foo1
或Foo2
,並依賴於多態性。
但帶走的是,有沒有辦法避免變化的所有地方method()
被稱爲...如果你希望能夠在運行時Foo1.method
和Foo2.method
之間做出選擇在你的代碼的地方。
爲什麼需要動態加載類,而不是僅創建Foo1和Foo2的單獨實例? – 2011-02-14 23:35:30
我猜他的問題在於Foo1和Foo2的方法是靜態的。這有點奇怪,對同一個操作有不同的實現通常意味着他不應該使用靜態方法,但很難判斷這個通用的例子。史蒂夫,這些課程實際上做了什麼?如果他們的合同是一樣的,爲什麼你不使用接口? – PaoloVictor 2011-02-14 23:42:29
你確定`method()是靜態的嗎?它從提供的代碼看起來並不那樣。 – CurtainDog 2011-02-14 23:54:17