2012-08-31 100 views
2

我很感兴趣,为什么这个代码片段生成一个语法错误说ImmutableMap不能被解析为一个类型:尽管此代码按预期工作泛型方法的类型参数是做什么的?

ImmutableMap<String, String> advice = ImmutableMap<String, String>.builder() 
        .put(KEY1, VAL1) 
        .put(KEY2, VAL2) 
        .build(); 

ImmutableMap<String, String> advice = ImmutableMap.<String, String>builder() 
        .put(KEY1, VAL1) 
        .put(KEY2, VAL2) 
        .build(); 

期间不会我的心理模型应该在哪里,我希望有人能够解释为什么这个时期的“方法方面”会出现。我正在使用番石榴的ImmutableMap,但它不完全相关,我不认为。我认为这与泛型有关,但我不确定如何搜索以找到更好的答案,因为我不知道该概念会被调用。

编辑:作为参考,ImmutableMap具有此线为builder()

public static <K, V> Builder<K, V> builder() { 
    return new Builder<K, V>(); 
} 
+0

http://stackoverflow.com/a/55679/829571 – assylias

+0

可能重复[使用Java Guava库,如何使用Builder创建ImmutableSortedSet?](http://stackoverflow.com/questions/6362856/using-the-java-guava-library-how-to-create-a-immutablesortedset-using-a-builder) – Xaerxess

回答

6

建设者()是具有与它相关的通用类型的静态方法,而不是它的类中定义它将会像

public static <K,V> ImmutableMap.Builder<K,V> builder() { ... } 

注:这里的<K, V>不会有什么使用类的通用类型。 (这不一定是通用的)

+0

所以,我试图用@David M把你的答案和其他答案拼凑在一起。因为这是一个静态方法,并且泛型类型实际上并没有与类一起加载到类加载器中,所以该方法需要传入类型信息? 因此,当我读取您发布的行时,是否应将其读为: ImmutableMap < - return type |方法 - > builder()?如在方法签名中包含指示泛型类型的要求? –

+0

从概念上讲,它是具有泛型类型的方法的签名。在这种情况下,泛型类型不会在运行时传递或可用。 –

1

的由于Java实现泛型方式,通过类型擦除(铸造)不扩张,则实际上只有一个ImmutableMap类加载。它的静态builder方法因此需要解决特定的泛型过载问题。变量advice被声明为ImmutableMap<String, String>是编译器的语法糖,然后在上调用实例方法时,该变量将承担相关的过载。但是,必须单独指定在ImmutableMap上的静态方法调用。这就是为什么泛型出现在点的方法一侧。

这将是由膨胀实现泛型,如C#,其中每个通用映射类型会被加载为单独类型到CLR语言不同,所以ImmutableMap<String, String>将是一个不同类型的具有不同的静态方法来ImmutableMap<Foo, Bar>

0

很难找到关于这个概念的信息,因为它有点模糊。我不得不寻找Angelika Langer的泛型常见问题一段时间才能找到它,尽管我知道它...

无论如何,它被称为“显式类型参数说明”,它用于当您要指定类型参数为一个通用的方法明确,通常是因为编译器不能从上下文推断它(如链接方法调用时),或者是因为你想帮助各种重载的编译器选择:

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ402

更多信息上类型自变量推理:

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ400

相关问题