为什么 Java 不允许你从泛型类型变量继承?


public class MyClass<T> extends T {...}

上述声明将无法编译并显示错误:

error: unexpected type
class MyClass<T> extends T {}
^
required: class
found:    type parameter T
where T is a type-variable:
T declared in class MyClass

我真的想不出发生这种情况的原因,所以我想知道是否有人可以阐明为什么 Java 不允许你从泛型类型变量继承。

我能想到的最明显的原因甚至不是关于类型擦除;事实上,当你把A作为B的子类时,Java编译器需要知道B有什么构造函数。如果类没有无参数构造函数,则其子类必须调用其定义的构造函数之一。但是当你宣布

public class MyClass<T> extends T {...}

编译器绝对不可能知道super构造函数是什么,因为 T 在编译时不是固定的(毕竟这是泛型的全部意义(,这是 Java 中不允许的情况。

Java有很多语言限制,不像C++。由于注释中列出的许多原因(T可能是final或具有abstract方法(,您想要的是不可能的。但是,允许您从具有泛型类型参数的超类型扩展:

public class MyClass<T> extends AnotherClass<T>

您可能会发现以下替代方法很有趣:

public class MyClass<T extends AnotherClass> extends AnotherClass

你想做的事情没有多大意义。

你的问题并不像看起来那么奇怪:)考虑您将如何处理以下问题:

  1. 假设 T 的实际类有一个带有 3 个参数的构造函数。如果您不知道如何调用超级构造函数,您将如何实现继承类的构造函数?

  2. 假设 T 的实际类具有公共 final 方法,并且您在继承的类中定义了具有相同签名的方法。您的对象将具有什么方法?你无法解决这种冲突。

根据您的问题进行简单的推论。

T 是一种类型。

MyClass 扩展 T - MyClass 是 T 的增强版本。

MyClass扩展了 T - MyClass 是增强型 T,但仅适用于类型 T。

没有理由说"我扩展了T,但仅适用于T型"。

如果你扩展T,MyClass已经是T的类型,绝对不是X,Y或Z。

如果要确保类型安全,则需要泛型,如果扩展它已经是类型安全的。

最新更新