2014-10-28 266 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的工廠方法,但該方法不需要任何東西,因此沒有任何東西可以採用該類型。