如何推断这些Java泛型语法的返回类型?

时间:2014-10-28 19:23:02

标签: java generics

我在Java中看到了这种语法

ImmutableMap.Builder<String, Object> builder = ImmutableMap.<String, Object>builder()

在左侧我可以理解Builder采用String和Object两种类型。但右手sytax让我很困惑。 当我读到它时

  1. ImmutableMap.XXX // XXX应该是属性或静态方法。
  2. 好吧,我发现Immutable.<String, Object> //为什么XXX现在是<String, Object>,是一种通用类型?
  3. 接下来,Immutable.<String, Object>builder(); //现在,这是一个builder()返回类型吗?它将返回Immutable.<String, Object>。构建器现在如何表现为独立功能。
  4. 你可以看到我在Java中被这种语法所困扰。我如何最好地理解这些语法?

    一个更简单的例子是,在单元测试中,我必须这样做。

    expect(mockDao.findId(role, name)).andReturn(Optional.<Long>absent());
    

    absent()是Optinal的通用静态方法,我会理解它是否是Optional.absent(),但是使Optional.<Long>absent()而不是Optional<Long> Optional.absent()让我感到困惑。

    我应该研究哪些消息来澄清我对这个概念的理解?

2 个答案:

答案 0 :(得分:3)

大多数情况下,当方法是通用的时,例如:

public static <T> Optional<T> absent()

编译器可以从上下文中自动推断正确的泛型类型。例如:

Optional<String> opt = Optional.absent();

调用Optional的通用静态方法absent(),编译器从分配了结果的变量opt的类型中推断出方法(String)的泛型类型。

但有时候,它无法推断它,或者推断出你想要的其他类型,比如

Set<Object> set = Collections.singleton("foo");

要指定要使用哪种泛型类型,语法是在方法名称之前指定泛型类型:

Set<Object> set = Collections.<Object>singleton("foo");

答案 1 :(得分:0)

你必须以某种方式提供类型。如果我有

public static <T> T getRandom(List<T> list) { ... }

这是一个从列表中返回随机元素的方法,该类型是从我传入的对象中推断出来的:

List<String> list = // whatever
String randomString = getRandom(list); // <- the type String gets filled in here

但是,如果我的情况是无法推断出类型,那么必须提供它,并且那种看起来很笨拙的“点后”语法是Java的做法。看起来builder()是制作新ImmutableMap.Builder的工厂方法,但该方法不会采取任何措施,因此无法从中获取类型。