为什么我必须在 return 键入 Java 之前声明类型参数?

Why I must declare type parameter before return type in Java?

在不介绍泛型的情况下,我会直接 post 我的问题。为什么这是正确的:

static<T extends Object> void m1(List<T> list){
        //some code
    }

这不是(不编译):

static void m2 (List<T extends Object> list){
        //some code
    }

请记住,我们可以在相同的方法中使用 通配符 ,这样可以很好地编译:

static void m2 (List<? extends Object> list){
        //some code
    }

综上所述,为什么我们可以在参数中使用通配符声明,而使用类型参数必须在[=30之前声明] =]类型?

主要有两点。

首先,正如@akuzminykh 在对问题的评论中所说,? 通配符基本上只是一种告诉编译器“我不知道这会是什么,只是假设它可以是从 class/interface 派生的任何东西,kthxbye”。它没有声明您可以在方法中使用的任何参数,没有您可以调用的标识符,什么都没有。然而,类型参数正是这样做的,如果你声明一个新的,这与仅仅“调用”你不必声明的通配符是不同的故事。

其次,考虑如何为泛型声明类型参数 class。你觉得这样就够了吗?

public class Foo {
    public T extends CharSequence getBar() {...}
}
public class Foo {
    public <T extends CharSequence> getBar() {...}
}

不,这两个选项中的 none 都可以。为了在 class 中使用泛型类型参数,您必须将其与类型本身一起声明,而不是与使用它们的 methods/fields 一起声明。像这样:

public class Foo<T extends CharSequence> {
    public T getBar() {...}
}

并且为了在方法中使用泛型类型参数,您必须将其与方法本身或包含该方法的类型一起声明,而不是与使用它们的方法参数一起声明。