为什么我必须在 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() {...}
}
并且为了在方法中使用泛型类型参数,您必须将其与方法本身或包含该方法的类型一起声明,而不是与使用它们的方法参数一起声明。
在不介绍泛型的情况下,我会直接 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() {...}
}
并且为了在方法中使用泛型类型参数,您必须将其与方法本身或包含该方法的类型一起声明,而不是与使用它们的方法参数一起声明。