繁体   English   中英

Java方法和泛型

[英]Java methods and generics

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

public static <T, K> void delete(AbstractDao<T, K> dao)

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

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

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

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

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

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

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

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

public static void delete(AbstractDao<T, K> dao)

编译器不会知道TK应该是方法类型参数(从方法调用推断)。 它会期望TK已经被声明(例如导入),因为这些是泛型的用法 ,而不是声明。

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

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

public class MyClass<T> {
}

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


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

public static <T extends Pony, K> void delete(AbstractDao<T, K> dao)

虽然这不是:

public static <T, K> void delete(AbstractDao<T extends Pony, K> dao)

为什么编译器不聪明?

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

在大多数情况下,您的方法不是通用的。 在大多数情况下,如果已经实际定义了Something则会使用List<Something>类的参数。 想象一下,如果你只是忘记导入Something类......

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

有关更权威和完整的文档资源,请参阅Java语言规范。 特别是在这个案例的8.4节方法声明中 ,他们明确提到了类型参数:

方法声明可以调用的可执行代码,将固定数量的值作为参数传递。

MethodDeclaration:

{MethodModifier} MethodHeader MethodBody

MethodHeader:

Result MethodDeclarator [Throws]

TypeParameters {Annotation} Result MethodDeclarator [Throws]

MethodDeclarator:

Identifier ( [FormalParameterList] ) [Dims]

来自http://math.hws.edu/javanotes/c10/s5.html “我们需要使用类型参数的名称替换方法定义中的特定类型String,例如T.但是,如果这是只有我们改变,编译器会认为“T”是实际类型的名称,它会将其标记为未声明的标识符。我们需要某种方式告诉编译器“T”是一个类型参数。这就是什么<T>在泛型类“class Queue <T> {...”的定义中执行。对于泛型方法,<T>就在方法的返回类型的名称之前“所以,< T>在方法名称告诉编译器方法签名中的T不是实际类型,而是泛型。

泛型只是“泛型类型”的缩写,可以表示返回类型或参数类型(如您的情况: AbstractDao<T, K> )。 并且语言的语法要求在泛型类型中指定的类型变量应该在方法的返回类型之前声明,以便它们可以包含返回和参数类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM