2014-10-28 138 views
0

我遇到这种语法在Java中如何推断这些Java泛型语法的返回类型?

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

在左边我可以理解生成器有两种类型的字符串和对象。但是右手版本让我感到困惑。 当我读它

  1. ImmutableMap.XXX // XXX应该是属性或静态方法。
  2. 嗯,我觉得Immutable.<String, Object> //为什么现在XXX是<String, Object>,泛型类型?
  3. 接下来,Immutable.<String, Object>builder(); //现在,这是一个建设者()的返回类型?它会返回Immutable.<String, Object>。建设者现在如何像独立功能一样行事。

你可以看到,我有点这个语法在Java中难住了。我如何最好地理解这些类型的语法?

一个简单的例子是,在一个单元测试,我不得不做。

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

不存在()是Optinal的一个通用的静态方法,我会明白,如果它是Optional.absent(),但反而使得它Optional.<Long>absent()Optional<Long> Optional.absent()混淆了我一下。

任何来源,我应该考虑到我澄清这个概念的理解?

+0

有意思的是,当方法不是泛型时,将任何泛型类型规范添加到任何方法调用显然是合法的。 '的System.out。 println(“Hello!”。 toString())' – zapl 2014-10-28 19:41:53

回答

3

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

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

编译器能自动推断从上下文右侧一般类型。例如:

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

调用通用静态方法可选的absent()和编译器推断所述类型从可变opt的类型的方法(字符串),向其中结果被分配。

但有时,它不能推断它,或者推断另一个类型的比你想要的,就像在

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

要指定要调用的方法与泛型类型,语法是在方法名称前指定通用类型:

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

谢谢!这解释清楚。为什么类型的怪癖是在课后给出的。和之前的方法名称?它可能是' Collections.singleton(“foo”)'(类型类型铸造的排序)? – 2014-10-28 21:05:51

+0

如果你想做'String foo = SomeClass,该怎么办? bla()。 bling()。 ()。 bizz()'? – 2014-10-28 21:08:18

+0

嗯。有趣。我明白了。根据我的思考过程,这可能是'(( SomeClass.bla()).bling()).bing()).bizz())' – 2014-10-28 23:55:31

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的工厂方法,但该方法不需要任何东西,因此没有任何东西可以采用该类型。