当我有一个Java泛型函数时:
<T> T choose(T a, T b) { }
我从某个地方调用它,如何找出推断出T的类型?
编辑:类型推断在编译时发生。所以我要问的是,如何让编译器告诉我在编译期间它有一些信息(推断类型),但这不会进入.class文件?
我能做的一件事是尝试将结果分配给各种类型的变量,例如:
// Compiles, so inferred type is at least Throwable.
Throwable foo = choose(new EOFException(), new FileNotFoundException());
// If this compiles, T must be Map or something that implements Map.
Map foo = choose(new HashMap(), new TreeMap());
但这是间接的。我希望编译器告诉我它推断T的类型,而不是我必须发出20个问题。
答案 0 :(得分:3)
在eclipse中,将鼠标悬停在方法调用表达式上。 Eclipse将使用推断类型显示签名。
修改:看来这确实并非总是正确的。对于以下声明
interface I {void foo();}
class C {}
class D extends C implements I { public void foo() {}}
class E extends C implements I { public void foo() {}}
和表达,
java.util.Arrays.asList(new D(), new E()).get(0).foo();
显示的推断类型为? extends C
,但实际推断类型为? extends C & I
,允许访问foo
即表明这一点。我不知道为什么eclipse显示的内容与其内置编译器推断的类型不同......
答案 1 :(得分:0)
我希望在编译阶段(c.f. Scala)发生类型推断,所以我对你的问题感到有些困惑。
Java在实现泛型时使用type erasure。但请注意,类型推断是proposed for Java 7。
答案 2 :(得分:0)
嗯,考虑到你的两个例子,你不必期望一个特定的类型。 编译器将最具体的公共类型作为“T”,如果这个“类型”是一个接口,那么你将拥有实现该接口的烦人类的实例(对于你的“foo”对象)。