2010-02-21 12 views
2

我有這樣的事情在我的Java程序回事:Java:如何編寫指定超類和接口的強制轉換?

void f(Object o) { 
    g(o); 
} 

<T extends MySuperClass & MyInterface> void g(T x) { 
    ...; 
} 

我怎麼能投Ø使這一工作?似乎沒有辦法在不使用泛型的情況下在變量聲明中指定基類和接口。我不認爲泛型將在這裏工作,因爲o是使用反射動態創建的,所以它的實際類在編譯時並不知道。 (我知道這是一件奇怪的事情,但我確實需要超類和接口的功能,我想我可以在運行時使用instanceof來完成所有的類型檢查,但是,似乎只是所以Java 1.4 ...)

回答

3

實例這似乎是沒有辦法調用「原始」通用方法。但是你可以創建原始類型的對象(以下轉換,顯然,不安全):

void f(Object o) { 
    Caster<?> c = new Caster(); 
    g(c.cast(o)); 
} 

class Caster<T extends MySuperClass & MyInterface> { 
    public T cast(Object o) { 
     return (T) o; 
    } 
} 
+0

太棒了!這有用,謝謝。 – ljp 2010-02-22 00:52:13

-1

難道是像

<T extends MySuperClass implements MyInterface> 

我只是猜測這裏...

+0

程序的「」是通用參數的正確語法。我需要的是匹配類型轉換。例如,我需要XXX的語法 g((XXX)o); – ljp 2010-02-21 23:52:33

+0

啊。我不需要真的擔心複雜的泛型和反射之前... – masher 2010-02-21 23:56:26

2

可以包含f()類中創建一個新的內部類呼籲g()

static abstract class MyCastingClass extends MySuperClass implements MyInterface {} 

然後你可以施放:

g((MyCastingClass)o); 

編輯:

這似乎並沒有工作,雖然。

它可以讓你的代碼進行編譯,並且沒有任何警告,但在運行時,你會得到一個ClassCastException除非你的對象實際上是MyCastingClass

+0

這是一種恥辱,不起作用。不錯,儘管如此。我越想越想,就越覺得它不可能。 Casting和變量聲明是指定動態類型的機制,動態類型不如在編譯時擦除的泛型類型那麼靈活。這看起來像是泛型實施中的一個明顯的漏洞,沒有明顯的方法來解決這個問題。 – ljp 2010-02-22 00:15:48

1

您可以使用反射來調用克,類似於以下,但對選擇正確的merhod更多的檢查,並處理異常:

Object dest_obj_containing_g = this; // Replace with your object. 
Method[] methods = dest_obj_containing_g.getClass().getDeclaredMethods(); 
for (Method m : methods) { 
    if (m.getName().equals("g")) { 
    m.invoke(dest_obj_containing_g,o); 
    break; 
    } 
} 
+0

絕對可怕!但它會起作用。謝謝=) – ljp 2010-02-22 00:52:35

+0

是的,但你說你已經在使用反射。不太可怕的是:'dest_obj_containing_g.getClass()。getDeclaredMethod(「g」,MySuperClass.class).invoke(dest_obj_containing_g,o);' – 2010-02-22 00:55:56

相關問題