这个Java函数从哪里推断出它的泛型类型?

时间:2013-01-10 16:53:44

标签: java generics

我发现了一些通用代码,它让我觉得它实际上是如何运作的。 我不明白它在哪里得到用于T的泛型类型。 这是一个过于简单的示例,但我仍然不明白这是如何有效的Java代码。

public static void main(String[] args) {
  System.out.print(get());
}

public static <T> T get()
{
  return (T) getObj();
}

public static Object getObj() 
{
  return Boolean.FALSE;
}

2 个答案:

答案 0 :(得分:3)

类型推断基于调用点发生。

但是,如果将返回值分配给变量,则类型推断仅适用于返回类型。 这是用spec

写的
  

如果方法结果发生在将要进行赋值转换的上下文中,则[...]

否则,任何未解析的类型参数总是变为Object 在您的示例中,这将起作用,因为存在print(Object)重载。

另一方面,看看这段代码:

print(get());

public void print(Boolean x) { }

public <T> T get() {
    return (T) Boolean.FALSE;
}

这会产生编译错误,因为编译器在查看get()之前会将Object推断为返回print()

答案 1 :(得分:1)

在您编写的代码中,T 未绑定。每当你调用get方法时,Java都会为T分配一个类型,它会查看你期望返回的类型......但是只有当你明确声明你在等待哪种类型时,这似乎才有效对于。请看以下示例:

public static void jump(String a) {
}

public static <T> T get() {
    return (T) null;
}

public static void main(String[] args) {
    //This works quite well, generic parameter T is inferred to be String
    String blah = get();
    jump(blah);
}

另一方面

public static void jump(String a) {
}

public static <T> T get() {
    return (T) null;
}

public static void main(String[] args) {
    //This doesn't work, Java does not bind T to anything hence Object is used... and no jump for object is found
    jump(get());
}

至少这是它在Java 6上的工作方式。