为什么没有';Java是否将现有的类语言规范语法用于泛型类型规范?

为什么没有';Java是否将现有的类语言规范语法用于泛型类型规范?,java,generics,Java,Generics,这周我学习了更多关于Java泛型的知识。我在指定泛型时学习了有界类型。描述大致如下: class <T extends A & B & C> ... 类。。。 这意味着T必须属于扩展a并实现B和C的类型。因此,在泛型定义中,类型T的实例可以访问a、B或C的任何方法 T只能扩展一个类,它必须是列表中的第一个类。所有扩展也可以是接口 这种表示法可能令人困惑。A是否是一个类并不明显。如果您犯了错误,并且B是类,编译器将不允许您继续,但它不会给出一条特别明显的编译时错误消

这周我学习了更多关于Java泛型的知识。我在指定泛型时学习了有界类型。描述大致如下:

class <T extends A & B & C> ...
类。。。
这意味着T必须属于扩展a并实现B和C的类型。因此,在泛型定义中,类型T的实例可以访问a、B或C的任何方法

T只能扩展一个类,它必须是列表中的第一个类。所有扩展也可以是接口

这种表示法可能令人困惑。A是否是一个类并不明显。如果您犯了错误,并且B是类,编译器将不允许您继续,但它不会给出一条特别明显的编译时错误消息。它没有说,“B类必须是列表中的第一个。”

我认为Java已经有了定义类和接口的方法。为什么不利用泛型的现有语法呢。因此,不是:

class <T extends A & B & C>
为什么不:

class <T extends A implements B, C>

这里一定有些混乱。扩展与实现没有什么不同。通过不需要实现,Java允许用户将类或接口传递到泛型中。如果你从设计的角度考虑问题

class <T extends A & B & C>


执行相同的操作,但是如果希望将接口作为第一个类型传递,则
class
需要创建一个新类。使用
extends
而不是
implements
在接口和类之间创建了一种可互换的关系,从而允许更好的代码设计。

您将泛型类型参数中的
extends
关键字与类声明中的
extends
关键字混淆了,并且
扩展接口声明中的
关键字

在这些上下文中,关键字的含义并不相同

声明说
类a扩展B实现C,D
,则
B
必须为
类型,而
C和
D
必须为
接口类型

接口
声明说
接口A扩展了B、C
,那么
B
C
必须是
接口
类型

当泛型类型声明表示
,则
B
可以是
接口
,而
C
D
必须是
接口
类型

如您所见,
extends
关键字本身并没有指定类型必须是
class
类型还是
接口
。使用关键字的上下文定义了该关键字


现在,关于你的问题,为什么他们没有保留现有的语法

它们不能,因为如果将
更改为
,那么
C
D
是否是两个独立的参数,或者它们是否是
A
的附加边界,都是不明确的

问题是,参数列表已经使用逗号(
)来分隔参数,并且在声明多个基类型时,语法已经使用逗号(
)来分隔它们,因此,当您将两者结合在一起时,最终会导致语法不明确

他们必须更改其中一个,因此他们选择使用逗号作为参数分隔符,然后使用
&
分隔多个基类型


为什么不使用
?他们为什么要这样做<代码>扩展
已经可以用来引用类和接口,所以让它这样做并不是“新的”


还要记住,
A
本身可以是
接口
。因为它是类和接口的通用语法,所以他们为
选择了简单的通用语法,其中
TYPE
class
interface

“为什么”你必须问语言设计者。我怀疑这主要是个人喜好。我可以看到,稍微不同的语法使它更清晰,更容易阅读。但我只是在猜测原因。简短回答“为什么不:
class
”,因为
C
是第二个泛型类型参数,而不是
T
@andre的第二个边界。为了便于讨论,我们可以假设语法是
。@Kayaman,这是不同的语法,所以回到那个问题,然后。。。。哦,是的,我们刚刚解释了为什么语法必须不同,不是吗?我在a中也做了。@Andreas是的,但是你刚刚编辑了我在后面讨论的部分。你说“需要创建一个新类”是什么意思
class Foo
将是一个类,该类的用户唯一能影响的是
T
是什么(具有给定的约束)。约束已经给出,无论使用哪种语法都是不相关的。因为您谈论的是“将接口作为第一种类型传递”,您可能会将
A
B
C
与泛型类型混淆。但是,它们应该分别表示一个类和两个接口。它们不会被传进来,它们是用石头写的。只有一种泛型类型
T
。我不确定原始海报所指的其他实现泛型语法标准的语言是什么,但是,如果关键字
extends
用于要求一个类扩展另一个类,并且关键字
implements
保留用于接口实现,那么约束只能是类、接口、接口,而不是接口、接口、接口的可能性。基本上,我指的是约束设置的灵活性,而不是T可以设置的灵活性。似乎你得出了一些错误的结论。一旦你写了这个类,它就
class <T extends A implements B, C>