首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >芭乐反向源码奇怪的通用语法

芭乐反向源码奇怪的通用语法
EN

Stack Overflow用户
提问于 2013-06-30 05:31:19
回答 2查看 146关注 0票数 0
代码语言:javascript
复制
 /**
   * Returns a reversed view of the specified list. For example, {@code
   * Lists.reverse(Arrays.asList(1, 2, 3))} returns a list containing {@code 3,
   * 2, 1}. The returned list is backed by this list, so changes in the returned
   * list are reflected in this list, and vice-versa. The returned list supports
   * all of the optional list operations supported by this list.
   *
   * <p>The returned list is random-access if the specified list is random
   * access.
   *
   * @since Guava release 07
   */

  public static <T> List<T> reverse(List<T> list) {
    if (list instanceof ReverseList) {
      return ((ReverseList<T>) list).getForwardList();
    } else if (list instanceof RandomAccess) {
      return new RandomAccessReverseList<T>(list);
    } else {
      return new ReverseList<T>(list);
    }

我以前从未见过这样的语法:

代码语言:javascript
复制
 public static <T> List<T> reverse(List<T> list)

<T> List<T>到底是什么意思?我想应该是:

代码语言:javascript
复制
 public static List<T> reverse(List<T> list)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-30 06:10:21

你的假设代码是:

代码语言:javascript
复制
public static List<T> reverse(List<T> list)

甚至不会编译。

为什么?因为编译器未知T泛型类型的T实体。

当我们在一个方法的上下文中时,如果你声明一个泛型类型,它必须来自某个地方。在您提出的声明中,除非包含的类声明了T,否则编译器无法将其与之关联。

当你在一个只有实用函数的静态类的上下文中时,这个类肯定不是泛型的;因此需要告诉编译器“嘿,这个方法必须有一个泛型类型,它在这里叫做T”。但它也可以被称为MEH

代码语言:javascript
复制
public static <MEH> List<MEH> reverse(List<MEH> list)

从本质上讲,规则是:

  • 如果这是一个链接到泛型类本身的实例的方法,您可以在方法中自由地重用该类的泛型类型声明,而不必重新声明泛型类型(这就是为什么,例如,Collection.iterator()方法不必重新声明泛型类型:Collection已经声明了它);
  • 另一方面,如果此方法不能链接到特定类的实例(这通常是静态方法的情况),则必须告诉该方法存在泛型类型,该方法的返回类型和/或参数应考虑该泛型类型。

既然您正在谈论Guava,那么让我们从Guava本身来看另一个例子:Closer。您可以通过调用以下方法创建实例:

代码语言:javascript
复制
final Closer closer = Closer.create();

然后该方法有一个.register()方法,该方法以“任何实现Closeable的类型”作为参数。这种方法的原型是:

代码语言:javascript
复制
public <C extends Closeable> C register(C closeable)

您将注意到Closer类本身不是泛型的;但是,它的.register()方法确实有一个泛型绑定的参数:它通过声明的优点要求C必须实现(在本例中)/extend Closeable

这个方法的参数和返回类型都恰好是那个C,这就是为什么你可以像这样提交一个FileInputStream

代码语言:javascript
复制
final FileInputStream in; // implements Closeable

try {
    in = closer.register(new FileInputStream("meh"));
    // etc
票数 3
EN

Stack Overflow用户

发布于 2013-06-30 05:32:51

第一个<T>显示它是一个generic method,将T作为type variable引入。不要忘记Lists本身不是泛型类型-所以如果它只是

代码语言:javascript
复制
public static List<T> reverse(List<T> list)

..。你希望T指的是什么?

有关详细信息,请参阅Java Generics FAQ entry for generic methods

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17384886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档