java - 为什么泛型方法和泛型类型有不同的类型引入语法?

标签 java generics

在学习泛型时,我注意到 generic methods 之间的类型介绍语法有所不同。和 generic types (类或接口(interface))让我感到困惑。

泛型方法的语法是

<T> void doStuff(T t) {
    // Do stuff with T
}

文档说

The syntax for a generic method includes a type parameter, inside angle brackets, and appears before the method's return type

泛型类型的语法是

class Stuff<T> {
    // Do stuff with T
    T t;
}

文档说

The type parameter section, delimited by angle brackets (<>), follows the class name. It specifies the type parameters

因为它没有说明为什么它必须在之前或之后。


为了彼此一致,我希望方法语法是
void doStuff<T>(T t) {}或类型语法(对于类)为 class <T>Stuff {} ,但显然不是这样的。

为什么要先介绍一个,后要介绍另一个?

我主要以 List<String> 的形式使用泛型。并争辩说<String>List可能看起来很奇怪,但这是一个主观的论点,除了方法之外,它也是如此。您可以调用doStuff喜欢 this.<String>doStuff("a string");

寻找技术解释,我想也许 <T>必须在指定返回类型之前将其引入方法,因为 T可能返回类型,编译器可能无法像那样向前看,但这听起来很奇怪,因为编译器很聪明。

我认为除了“语言设计者就是这样设计的”之外,还有其他解释,但我找不到。

最佳答案

答案确实在于GJ Specification ,已链接,引自文档,第 14 页:

The convention of passing parameters before the method name is made necessary by parsing constraints: with the more conventional “type parameters after method name” convention the expression f (a<b,c>(d)) would have two possible parses.

评论实现:

f(a<b,c>(d))可以解析为 f(a < b, c > d) 中的任何一个(传递给 f 的比较中的两个 boolean 值)f(a<B, C>(d)) (使用类型参数 B 和 C 以及传递给 f 的值参数 d 调用 a)。我想这可能也是 Scala 的原因选择使用[]而不是 <>用于泛型。

关于java - 为什么泛型方法和泛型类型有不同的类型引入语法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45568008/

相关文章:

java - 泛型 java 中的逆变不能按预期工作

c# - 避免在基类中使用泛型列表——我应该对字典遵循相同的规则吗?

Java 套接字异常 : Socket Closed and null value

java - 通过 Spring Boot java 本地访问时,Aws Elasticache (Redis) 无法连接(jedis 连接错误)

java - 如何&& if循环表达式求值?

swift - 为什么这个 Swift 代码不进行类型检查?

arrays - 无法将协议(protocol)数组分配给通用数组

java - Eclipse 版本 : Mars. 1 版本 (4.5.1) 中缺少数据源资源管理器选项卡

java - 使用 YouTube 数据 API V3 按关键字搜索视频

.Net 2.0 - 通用列表的效率如何?