2010-03-17 135 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设计,未经检查的转换警告是无法合理避免的。我建议保持这种封装私有方法的严密性。