【问题标题】:Explain the syntax of Collections.<String>emptyList()解释 Collections.<String>emptyList() 的语法
【发布时间】:2015-02-25 08:06:19
【问题描述】:

我刚学过泛型编程,List&lt;E&gt;接口,ArrayList,所以能看懂下面的说法。

ArrayList<String> list = new ArrayList<String>();

但我不明白我在网上冲浪时看到的下一条语句。

List<String> list2 = Collections.<String>emptyList();
  1. 什么是Collections?为什么不是Collections&lt;E&gt;Collections&lt;String&gt;
  2. 为什么&lt;String&gt;放在方法名emptyList之前?

emptyList&lt;String&gt;() 不适合 Generic 吗?)

  1. 这句话是什么意思?

【问题讨论】:

  • Collections 是一个 Java 类。
  • 这是一个完全有效的问题。不确定它是否受到如此严厉的对待。对于不了解静态方法泛型的人来说,这可能是一个令人困惑的说法。投票重新开放。
  • 也投票重新开放。问题的 title 可能过于宽泛,但正文中的实际问题非常具体。也许编辑标题比关闭更好。
  • 在我看来,回答这个问题需要解释的概念数量如此之多,以至于一个答案几乎可以构成一个介绍 Java 教程。但是here's my explanation of generic methods。至于问题 2,请阅读静态导入。
  • @ChrisMartin 查看给出的答案。他们似乎做得很好。 OP 理解泛型,但 method 泛型是一个(可以理解的)新概念,在野外并不常见。

标签: java generics collections


【解决方案1】:

该行通过调用带有泛型类型参数的静态方法来创建一个空的字符串列表。

Collections 类中,有一个静态方法emptyList 声明如下:

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

这有一个泛型类型参数T。我们通过以下方式调用这个方法:

List<String> list = Collections.emptyList();

并且T 被推断为String,因为list 的类型。

我们也可以在调用emptyList时,将T的类型放在尖括号中。如果我们想要比推断出的更具体的类型,则可能需要这样做:

List<? extends Object> list = Collections.<String>emptyList();

emptyList&lt;String&gt;() 不正确,因为该位置仅在创建时有效 泛型类的实例,而不是调用方法。使用new 时有两种可能 类型参数,类名前的参数只用于构造函数,类名后的参数是整个实例,所以对于类:

class MyClass<A> {
    public <B> MyClass(A a, B b) {
        System.out.println(a + ", " + b);
    }
}

我们可以调用它的构造函数,其中AStringBInteger,例如:

MyClass<String> a = new <Integer>MyClass<String>("a", 3);

或使用类型推断:

MyClass<String> a = new MyClass<>("a", 3);

另请参阅:

【讨论】:

  • 可能要提一下Collections 是那些提供静态方法的类之一;它不打算被实例化(反过来也不能)。
  • 我不是 Java 专家,但在我看来,foo&lt;T&gt;() 根本不是“调用构造函数”,即使生成的对象构造结果在调用foo 的构造函数时(在所有其他步骤中实例化foo)。然后,与通用方法调用语法&lt;T&gt;bar() 没有实际的不一致或差异(我只想说,它来自 C++ 背景,非常奇怪!)。
  • 我检查了构造函数的语法,结果发现构造函数也可以有自己的类型参数,所以我们可以有两个类型参数表达式的语法,比如new &lt;String&gt;MyClass&lt;Integer&gt;(2)
  • @fgb 嗯……这是新的。我想我从来没有在野外见过这样的东西。有趣!
  • "emptyList() 是不正确的,因为该放置仅在调用构造函数时有效,而不是静态方法" 该语句令人困惑;因为这个问题是关于泛型方法的,所以听起来你在谈论泛型构造函数。但你不是。 SomeClass&lt;String&gt;() 用于创建具有非泛型构造函数的泛型类的实例。要使用泛型构造函数创建类的实例,您可以执行 new &lt;String&gt; SomeClass() 之类的操作。
【解决方案2】:

简而言之,这会创建一个空的、不可变的字符串列表。

让我们一点一点地看一下表达式。

Collections 是类的名称。来自Javadoc

该类仅由操作或返回集合的静态方法组成。它包含对集合进行操作的多态算法,“包装器”,它返回由指定集合支持的新集合,以及一些其他零碎的东西。

emptyList() 是在 Collections 类 (Javadoc) 中定义的静态方法的名称。是泛型方法,Collections.&lt;String&gt;emptyList()中的&lt;String&gt;指定泛型类型参数。

该方法返回一个List&lt;T&gt;,在本例中为List&lt;String&gt;:一个字符串列表。更具体地说,它返回一个不可变字符串列表。

【讨论】:

  • +1 用于突出显示(尽管文档中存在)返回集合的不变性
【解决方案3】:

Collections 是什么?为什么不是Collections&lt;E&gt;Collections&lt;String&gt;

Collections 是一个 JDK 类。

这个类完全由静态方法组成,这些方法在或 返回集合。它包含操作的多态算法 集合,“包装器”,它返回一个由 a 支持的新集合 指定的集合,以及其他一些零碎的东西。

它不是通用的,无法实例化。

为什么&lt;String&gt;放在方法名emptyList之前?

Collections#emptyList 是一个通用方法。在这里,我们明确指定了一个类型参数,String

emptyList&lt;String&gt;() 对 Generic 不正确吗?)

不,在 Java 中,方法的泛型类型参数位于方法名称之前。

这句话是什么意思?

我们正在调用静态emptyList 方法并将其返回值分配给List&lt;String&gt; 类型的变量。

【讨论】:

    【解决方案4】:

    首先,Collections 是一个静态方法的辅助库,可对各种类型的集合进行操作。如果您做过任何类型的 C++ 编程,那么它就是 &lt;algorithm&gt; 函数库的同义词。

    在这种情况下,您正在调用静态方法emptyList(),它返回一个特定类型的空列表。由于这些方法仍然需要类型,但Collections' 方法可以引用多种类型,因此您必须在调用时指定类型。

    为了调用一个通用的方法,你必须用参数列表(即&lt;String&gt;在方法名之前调用它,但之后 点。

    List<String> someList = Collections.<String>emptyList();
    

    【讨论】:

      【解决方案5】:

      1.Collection 是一个接口,而 collections 是一个静态类,仅由对集合进行操作或返回集合的静态方法组成。因此我们不能使用Collections&lt;E&gt;Collections&lt;String&gt;

      2.&lt;String&gt;在emptyList之前(用于获取不可变的空列表)表示只能向其中添加String值。喜欢:

      list2.add("A");
      list2.add("B");
      

      3.该语句表示它将创建一个List类型的不可变空列表。

      您可以查看此链接:Difference between Java Collection and Collections

      【讨论】:

      • denotes that only String values can be added to it. 更准确的描述是:将方法的参数类型声明为String,这样返回值就是String的同构List。
      猜你喜欢
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多