如何让Java编译器告诉我它推断出的类型?

时间:2009-12-05 12:42:29

标签: java generics

当我有一个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个问题。

3 个答案:

答案 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”对象)。