2012-11-22 41 views
0

我不是專業的Java程序員,所以這個問題可能很簡單,但我已經在網上搜索了答案,但到目前爲止沒有發現任何東西。Java通用操作結果類型

比方說,我們在Java中的泛型類:

public class C1 <T, U> { 
    public /*TYPE*/ f(T t, U u) { 
    return t.g(u) 
    } 

的問題是 - 我怎麼能確定這個通用例子的結果的類型? 是不是有可能寫出類似typeof(t.g(u))的東西?

+1

什麼是'g'在'克(U)'? –

+0

g是類T的實例t的一個方法,它接受1個U類型的參數並返回X類型的結果。 –

+0

就目前而言,由於'T'沒有上限,所以甚至不能調用'tg() 。 'T'不是一個類,它是一個類型參數。 –

回答

3

因爲T是無限制類型,所以不能按原樣調用t.g(u)。您需要對其編譯時間進行約束,以便編譯器知道可用的方法。否則,您只能調用Object方法,因爲編譯器可以推斷的唯一一個關於T的擴展是Object

例如,如果你有一個接口G<U>g方法要撥打:

public interface G<U> { 
    R g(U u); 
} 

那麼你會指定T extends G<U>,它可以讓你打電話g()。現在你知道g()的返回類型是:它是R

public class C1<T extends G<U>, U> { 
    public R f(T t, U u) { 
     return t.g(u) 
    } 
} 

如果你想的g()結果依賴於類型TU,那麼你可以做這樣的事情:

public interface G<T, U> { 
    T g(U u); 
} 

public class C1<T, U> { 
    public T f(G<T, U> g, U u) { 
     return g.g(u) 
    } 
} 
+2

小心 - 您可以將'U'視爲具體類型和類型參數。 –

+0

@PaulBellora啊,是的。你是對的。固定。 –

2

您的代碼不會按原樣編譯,因爲沒有什麼可告訴編譯器t具有成員函數g。您需要聲明類型參數T作爲擴展某個基類或接口,確實聲明瞭g()方法。返回類型將是g的返回類型(可能是另一種參數類型)。

例如:

public interface Foo<X, Y> { 
    X g(Y u); 
} 

public class C1 <T extends Foo<X, U>, U, X> { 
    public X f(T t, U u) { 
     return t.g(u); 
    } 
} 

注意的是,如果返回類型X也是通用的,你需要在C1類來聲明一個單獨的類型參數吧。可替代地,可以聲明C1與單個參數化類型均勻地處理(例如,String×StringString):

public class C1 <T extends Foo<T, T>> { 
    public T f(T t, T u) { 
     return t.g(u); 
    } 
} 

的其他變型也是可能的。

0

如果你想強制噸至有法克,你必須聲明你的類是這樣的:

public class C1<T extends Ginterface, U extends SecInterface> { 
} 

而且這種方法的返回類型爲G函數的返回類型Ginterface