2010-03-17 136 views
0

我無法找到Java的這個問題的重複,雖然有很多C#的。如何調用泛型方法知道泛型返回的類型?

我有這樣的方法:

public <T> T getSomething() { 
// 
} 

根據T的類型,我將具有不同的返回。例如:

String a = getSomething(); 
int b = getSomething(); 

對於a,我的方法將返回一個特定String。對於b,它將返回一個特定的int。等等。

看來,這可以用C#中的typeof()完成。我怎樣才能在Java中實現它?

+0

究竟是什麼問題?你想知道哪些類型用於你的本地變量,或者如何動態地知道它在運行時會是什麼類型? – Romain 2010-03-17 20:37:33

+0

java中沒有typeof()的直接等價物。但是instanceof可能會爲你做詭計:(「testString」instanceof String)返回true。 – Tedil 2010-03-17 21:10:12

回答

1

不幸的是,這對於Java來說是不可能的,因爲它使用了一種名爲「type erasure」的技術,允許泛型在不改變JVM的情況下工作。結果是,當方法被調用時,它所知道的只是對象,所以它無法知道它將返回什麼類型。

+0

JVM已更改爲支持泛型。擦除的重點在於它允許使用1.5之前的代碼進行相對無縫的操作。它也消除了一些開銷。 – 2010-03-17 21:46:38

+0

除了支持修改後的類文件格式以包含其他元數據外,我無法找到有關JVM如何更改的參考。它如何消除開銷?據我瞭解,擦除類型意味着隱式投射,這增加了開銷。 – Gabe 2010-03-17 22:13:17

0

除非在getSomething方法中有一些代碼,否則您的示例不起作用。如果我寫

public <T> T getSomething(){ return null;} 

它編譯,但它沒有意義。但是,您通常會從上下文讓你T:

public class Foo<T>{ 
    public T getSomething()... 
} 
new Foo<String>().getSomething()... 

大概有不得不的東西在你的實現,它的類型知道。

0

在Java中,這將是比較正常的寫類似:

public <T> List<T> getSomeThings() { 
    // 
} 

這工作得很好。

可能直接相當於你已經看到了在C#中會去是這樣的:

public <T> T getSomething(Class<? extends T> clazz) { 
    // 
} 

但會使用反射,這幾乎可以肯定是一個壞主意。你可以,當然,避免反射使用沼澤標準廠房:

public <T> T getSomething(FactoryThing<? extends T> factory) { 
    // 
} 

有偶然的情況下推斷返回類型是非常有用的。例如,從Java 1.5的串行化流中讀取1.5以前的API設計,未經檢查的轉換警告是無法合理避免的。我建議保持這種封裝私有方法的嚴密性。