0
 /**
   * 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);
    }

我以前从未见过这种语法:

 public static <T> List<T> reverse(List<T> list)

究竟是什么<T> List<T>意思?我以为会是:

 public static List<T> reverse(List<T> list)
4

3 回答 3

8

第一个<T>表明它是一个泛型方法T作为类型变量引入。不要忘记它Lists本身不是泛型类型 - 所以如果它只是

public static List<T> reverse(List<T> list)

...您希望T指的是什么?

有关更多信息,请参阅Java 泛型常见问题解答条目以获取泛型方法

于 2013-06-29T21:32:51.430 回答
3

你假设的代码:

public static List<T> reverse(List<T> list)

甚至不会编译。

为什么?因为T实体,T泛型类型,对于编译器来说是未知的。

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

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

public static <MEH> List<MEH> reverse(List<MEH> list)

本质上,规则是:

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

既然你在谈论番石榴,让我们再举一个番石榴本身的例子:Closer. 您可以通过调用创建一个实例:

final Closer closer = Closer.create();

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

public <C extends Closeable> C register(C closeable)

您会注意到Closer该类本身不是通用的;.register()然而,它的方法确实有一个泛型绑定的参数:它要求C,根据它的声明,必须实现(在这种情况下)/extend Closeable

这个方法的参数和返回类型恰好都是 that C,这就是为什么你可以提交例如 aFileInputStream这样的:

final FileInputStream in; // implements Closeable

try {
    in = closer.register(new FileInputStream("meh"));
    // etc
于 2013-06-29T22:10:21.147 回答
1

正如@JonSkeet 解释编译器语义一样,无论如何,我将在这里添加一个自由文本解释它的用途

当您想要强制返回List<T>的元素与方法参数的元素具有相同的类型List<T> list (或者,就此而言,强制返回的类型与一个或多个参数类型)

于 2013-06-29T21:48:40.473 回答