我想知道如何在java中運行時識別子類。在我的程序中,我調用了一個返回超類對象的方法。該對象可以是其任何一個子類的實例。我想知道該對象是運行時哪個子類的實例,以便我可以將其轉換爲該子類並訪問子類方法。任何人都可以幫助我嗎?在對象上在運行時識別子類
感謝
我想知道如何在java中運行時識別子類。在我的程序中,我調用了一個返回超類對象的方法。該對象可以是其任何一個子類的實例。我想知道該對象是運行時哪個子類的實例,以便我可以將其轉換爲該子類並訪問子類方法。任何人都可以幫助我嗎?在對象上在運行時識別子類
感謝
調用getClass()的訪問類的對象,告訴您該對象的實際類型。然後,您可以將它與任何類的「.class」靜態成員進行比較。
if (obj.getClass().equals(Foo.class)) { ... }
然而,很多人會說你的建議是壞設計。確保它是必要的,並考慮替代品。在實現像equals()這樣的方法時通常是必需的。
我認爲instanceof是一種更好的方法,但是您得到我的投票指出這確實表明設計是錯誤的。 – Dustin 2009-11-02 06:51:40
通過equals()比較Class對象沒有意義。這可以替換爲簡單的==。 – 2009-11-02 10:10:14
考慮到問題陳述,我不同意instanceof是解決方案。他有興趣根據對象的確切類別採取行動,而instanceof並沒有完全捕捉到這種情況:只要參數與給定的類是分配兼容的,而不是僅僅是一個實例,情況就是如此。在某些情況下,這是等同的,但不是全部。 – 2009-11-02 17:43:16
您可以使用instanceof
運算符來測試對象的類型,然後進行轉換。
使用instanceof
運算符。像這樣
Superclass aSup = ...;
if(aSup instanceof Subclass) {
Subclass aSub = (Subclass) aSup;
aSub.subclass_method(...);
}
您可以使用instanceof來檢查對象是否是特定類的實例。例如:
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.meow();
} else if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
}
但是,過度使用instanceof(或向下轉換,就此而言)通常被認爲是設計不佳的標誌。反而利用多態性更好。例如,在Animal中有一個(可能是抽象的)「speak」方法,然後每個子類都有不同的實現。上面的代碼將被用電話代替說話了:
animal.speak();
+1,用於解釋使用'instanceof'是不良設計的一個症狀。 – Jesper 2009-11-02 10:22:11
注意,如果對象是一個類型分配給指定的 類的instanceof是真實的。以下(如上所述)將工作
if (o instanceof Cat.class) {
// ..
} else if (o instanceof Dog.class) {
// ..
} else {
throw IllegalArgumentException("Unexpected type");
}
但是,如果你引入一個新的貓的子類,例如虎然後 第一個子句將被觸發,除非你更新了所有代碼 這樣做。
您可能想要搜索雙重調度 必須做到上述,當然不知道你的問題 試圖解決這個可能不適用。
您可以像上面提到的那樣使用'instanceof'操作符和直接的Class對象比較。
但是,如果你想修改代碼以避免明確的檢查,我看到兩條路走:
interface Handler<T> {
void handle(T object);
}
Map<Class<?>, Handler<?>> HANDLERS = /* init handlers mappings */;
...
public void process(Object obj) {
Handler<?> handler = HANDLERS.get(obj.getClass());
if (handler == null) {
throw new IllegalStateException("bla-bla-bla, no handler is registered for class " + obj.getClass());
}
handler.handle(obj);
}
謝謝..現在我知道該怎麼做了,Iam試圖改變設計以避免這種編碼 – daniel 2009-11-02 09:34:27