Java方法和泛型

mat*_*red 8 java generics methods

为什么泛型被声明为方法的一部分?例如,在创建使用泛型的方法时,必须在方法修饰符之后包含泛型:

public static <T, K> void delete(AbstractDao<T, K> dao)
Run Code Online (Sandbox Code Playgroud)

方法的泛型部分未显示为方法声明的一部分.根据java文档,方法包含以下项目:

修改器 - 例如公共,私人和其他您将在稍后了解的内容.

返回类型 - 方法返回的值的数据类型,如果方法未返回值,则返回void.

方法名称 - 字段名称的规则也适用于方法名称,但约定略有不同.

括号中的参数列表 - 以逗号分隔的输入参数列表,前面是数据类型,括在括号中,().如果没有参数,则必须使用空括号.

参考:https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html

Jof*_*rey 10

这是因为您必须单独考虑泛型类型参数声明用法.

在没有第一个的方法声明中<T,K>,如下所示:

public static void delete(AbstractDao<T, K> dao)
Run Code Online (Sandbox Code Playgroud)

编译器不会知道它T并且K应该是方法类型参数(从方法调用推断).它会期望T并且K已经被宣布(例如进口),因为这些是仿制药的用法,而不是声明.

这就是为什么你需要在<T, K>编译器的修饰符之后的声明,告诉它T并且K是从方法调用推断出的类型参数.

当您声明这样的泛型类时,不会发生此问题:

public class MyClass<T> {
}
Run Code Online (Sandbox Code Playgroud)

因为这里没有其他含义T,只能是类型参数声明.


注意:您还可以区分声明和用法之间的区别,因为您可以在声明期间约束类型参数,但不能在使用期间约束类型参数.这是有效的:

public static <T extends Pony, K> void delete(AbstractDao<T, K> dao)
Run Code Online (Sandbox Code Playgroud)

虽然这不是:

public static <T, K> void delete(AbstractDao<T extends Pony, K> dao)
Run Code Online (Sandbox Code Playgroud)

为什么编译器不聪明?

你可以告诉我编译器可能很聪明,它可以看到没有声明类型,推断它应该是通用的.但如果是这样的话,那真是一团糟.

在大多数情况下,您的方法不是通用的.在大多数情况下,List<Something>将使用Something实际定义的参数.想象一下,如果你只是忘记导入Something课程......

编译器将假设一个泛型类型参数,由对象擦除,你不明白为什么你不能使用你的类的方法等.它需要一些时间才能意识到什么是错的,因为编译器会接受这样的声明.