我在Java中看到了这种语法
ImmutableMap.Builder<String, Object> builder = ImmutableMap.<String, Object>builder()
在左侧我可以理解Builder采用String和Object两种类型。但右手sytax让我很困惑。 当我读到它时
Immutable.<String, Object>
//为什么XXX现在是<String, Object>
,是一种通用类型?Immutable.<String, Object>builder();
//现在,这是一个builder()返回类型吗?它将返回Immutable.<String, Object>
。构建器现在如何表现为独立功能。你可以看到我在Java中被这种语法所困扰。我如何最好地理解这些语法?
一个更简单的例子是,在单元测试中,我必须这样做。
expect(mockDao.findId(role, name)).andReturn(Optional.<Long>absent());
absent()是Optinal的通用静态方法,我会理解它是否是Optional.absent(),但是使Optional.<Long>absent()
而不是Optional<Long> Optional.absent()
让我感到困惑。
我应该研究哪些消息来澄清我对这个概念的理解?
答案 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
的工厂方法,但该方法不会采取任何措施,因此无法从中获取类型。