【问题标题】:return type of generic, when to use <T>returnType<T> and when to just use returnType<T>?泛型的返回类型,何时使用 <T>returnType<T> 以及何时只使用 returnType<T>?
【发布时间】:2020-05-30 21:11:17
【问题描述】:

在泛型api中,为什么有时类型参数写在返回类型之前,有时不需要?

以以下两个 Steam API 为例

Stream<T>   limit(long maxSize)

<R> Stream<R>   map(Function<? super T,? extends R> mapper)

为什么Stream.limit的返回类型只能写成Stream&lt;T&gt;而不是&lt;T&gt; Stream&lt;T&gt;

何时使用&lt;T&gt; returnType &lt;T&gt;,何时使用returnType&lt;T&gt;

【问题讨论】:

标签: java generics return-type


【解决方案1】:

第一个示例中的T 是正在操作的Stream 的泛型参数,因此limit(...) 返回一个与调用limit(...) 的流相同的泛型类型的新Stream

在第二个例子中,生成的Stream 的泛型类型可能会改变,因此需要一个单独的泛型参数。在这种情况下,生成的Stream 的类型受mapper-lambda 的影响。例如,如果Persons 映射到它们的SocialSecurityNumber,那么初始Stream 将是Stream&lt;Person&gt;mapper 将是Function&lt;Person, SocialSecurityNumber&gt; 类型,而生成的Stream 将是@ 987654336@.

【讨论】:

    【解决方案2】:

    &lt;R&gt; Stream&lt;R&gt; 中的第一个&lt;R&gt; 只是方法签名的另一部分——类型参数。您不应该将 &lt;R&gt; Stream&lt;R&gt; 视为“一个”事物,就像您在问题标题中所做的那样。

    第一个&lt;R&gt;只是为了告诉你这个方法的类型参数是什么,所以map是一个泛型方法。 limit 不是通用方法,因为它的签名中没有这部分。

    您可能对limit 不是泛型方法感到困惑,因为它显然返回了包含泛型参数T 的东西。好吧,T 实际上是封闭类Stream&lt;T&gt; 的泛型参数,所以limit 不能真正返回除调用它的Stream&lt;T&gt; 之外的任何其他类型。如果你在Stream&lt;A&gt; 上调用limit,你不能指望它会给你一个Stream&lt;B&gt;。因此,limit 不是通用的。

    注意T也是map的参数列表。

    什么时候使用&lt;T&gt;returnType&lt;T&gt;,什么时候只使用returnType&lt;T&gt;

    这里最大的不同是&lt;T&gt; returnType&lt;T&gt; 使方法通用。 returnType&lt;T&gt; 不是泛型方法,只有当T 在上下文中确实存在 时才能使用。

    【讨论】:

    • 然后对于方法“static Stream concat(Stream extends T> a, Stream extends T> b)”,如果 已经在 Stream 接口中声明,为什么还需要Stream中的第一个
    • @user1169587 因为静态方法不能使用类的类型参数。见stackoverflow.com/questions/936377/…
    猜你喜欢
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 2020-01-28
    • 1970-01-01
    • 2021-01-04
    相关资源
    最近更新 更多