代码之家  ›  专栏  ›  技术社区  ›  Karl von L

为什么对泛型使用Collections.emptySet()在赋值中有效,而不是作为方法参数?

  •  53
  • Karl von L  · 技术社区  · 15 年前

    我有一个类,它的构造函数是这样的:

    public FilterList(Set<Integer> labels) {
        ...
    }
    

    我想建造一个新的 FilterList 具有空集的对象。遵循Joshua Bloch在其著作effectivejava中的建议,我不想为空集创建一个新对象;我就用这个 Collections.emptySet() 取而代之的是:

    FilterList emptyList = new FilterList(Collections.emptySet());
    

    这给了我一个错误,抱怨说 java.util.Set<java.lang.Object> java.util.Set<java.lang.Integer> . 好吧,这个怎么样:

    FilterList emptyList = new FilterList((Set<Integer>)Collections.emptySet());
    

    这也给了我一个错误!好吧,这个怎么样:

    Set<Integer> empty = Collections.emptySet();
    FilterList emptyList = new FilterList(empty);
    

    嘿,有用!但为什么呢?毕竟,Java没有类型推断,这就是为什么如果有,就会得到未检查的转换警告 Set<Integer> foo = new TreeSet() Set<Integer> foo = new TreeSet<Integer>() Set<Integer> empty = Collections.emptySet(); 在没有任何警告的情况下工作。为什么?

    4 回复  |  直到 12 年前
        1
  •  124
  •   Andrzej Doyle    15 年前

    犯罪嫌疑人 全部的 泛型信息已解析)您实际上无法确定方法参数的类是什么,因此无法推断。变量声明很好而且是常量,所以您可以。

    其他人可能会提供更多的细节和/或一个很好的链接

    在任何情况下,都可以为泛型调用显式指定类型参数,例如:

    Collections.<Integer>emptySet();
    

    Collections.<String, Boolean>emptyMap(); // Returns a Map<String, Boolean>
    

    在推理不起作用的情况下,这通常看起来比强制转换要干净一些。

        2
  •  7
  •   Andrei Fierbinteanu    15 年前

    尝试

    FilterList emptyList = new FilterList(Collections.<Integer>emptySet());
    

    // forces use of ArrayList as parameter instead of the infered List
    List<String> l = someObject.<ArrayList<String> methodThatTakesTypeParamForReturnType();
    
        3
  •  6
  •   jdmichal    10 年前

    您想这样做:

    FilterList emptyList = new FilterList(java.util.Collections.<Integer>emptySet());
    

    这说明 emptySet 其泛型参数应显式使用的方法 Integer 而不是默认值 Object . 是的,它的语法非常时髦而且不直观