【问题标题】:Is this code sample really returning the right parameterized types?此代码示例是否真的返回了正确的参数化类型?
【发布时间】:2009-10-16 17:18:22
【问题描述】:

我读过Beautiful code with Google Collections, Guava and static imports关于Java集合的文章,下面的sn-p引起了我的注意:

Map<String, Map<Long, List<String>>> map = Maps.newHashMap();

问题是,我不明白newHashMap 方法怎么可能返回Map&lt;String,Map&lt;Long, List&lt;String&gt;&gt;&gt;。他们是如何编写这段代码的?什么时候成为可能?我的印象是,您需要在构造函数调用中显式声明泛型参数。

【问题讨论】:

    标签: java generics collections


    【解决方案1】:

    您可以在方法调用上声明泛型参数,而不仅仅是整个类。如果您查看该方法的来源:

    public static <K, V> HashMap<K, V> newHashMap() {
        return new HashMap<K, V>();
    }
    

    您会看到它声明了两个通用参数 K 和 V,并将结果声明为 Map。编译器足够聪明,可以从 LHS 表达式中计算出 K 和 V。在您的情况下,K 是 String 而 V 是 Map&lt;Long, List&lt;String&gt;&gt;

    【讨论】:

    • 这是“发现”新事物吗?还是一直都在这里?
    • @Geo 它是 Java 5 的“新”。我不确定你的意思。
    • 我总是实例化泛型类,例如:Whatever&lt;WhateverType&gt; var = new Whatever&lt;WhateverType&gt;()。我不知道Whatever&lt;WhateverType&gt; var = new Whatever() 是合法的。
    • @Geo 这是一个“字面”声明。当您将变量声明为方法调用的结果时,结果会有所不同。
    • @Geo 顺便说一句,您的语法应该在 Java 7 中使用新的“类型推断”JSR 是合法的:javac.info/Inference.html
    【解决方案2】:

    查看来源。这个方法所做的只是提供了一个很好的捷径:

    public static <K, V> HashMap<K, V> newHashMap() {
      return new HashMap<K, V>();
    }
    

    这适用于任何参数,因为 HashMap 本身是通用的。

    【讨论】:

    • 没错,它提供了一个快捷方式。但是为什么不是Map&lt;whatever&gt; map = Maps.newHashMap&lt;whatever&gt;
    • @Geo - 我不明白你的评论是什么意思
    • 说,这个例子:ArrayList&lt;String&gt; list = new ArrayList&lt;String&gt;()。写ArrayList&lt;String&gt; list = new ArrayList()合法吗?我记得需要在等号两边明确提及参数。
    • @Geo 该声明不同于使用泛型参数调用方法。
    • 这是合法的,但会产生未经检查的警告。这个和上面的区别在于上面使用了一个通用的方法来实例化你的类。在你的情况下,方法是public static &lt;T&gt; ArrayList&lt;T&gt; newArrayList() { return new ArrayList&lt;T&gt;(); },你可以写List&lt;String&gt; myList = newArrayList();
    猜你喜欢
    • 2020-02-25
    • 2012-10-17
    • 2011-08-29
    • 1970-01-01
    • 2011-04-16
    • 2011-12-18
    相关资源
    最近更新 更多