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

时间:2018-06-09 14:37:39

标签: java generics

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不会让你继承一个通用的类型变量。

4 个答案:

答案 0 :(得分:2)

与C ++不同,Java有很多语言限制。由于评论中列出的众多原因(T可能是finalabstract方法),您无法获得所需内容。但是,您可以从具有泛型类型参数的超类型扩展:

public class MyClass<T> extends AnotherClass<T>

您可能会发现以下备选方案很有趣:

public class MyClass<T extends AnotherClass> extends AnotherClass

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

答案 1 :(得分:2)

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

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

编译器绝对不可能知道super构造函数是什么,因为T在编译时并不是固定的(毕竟这是泛型的整个点),这是一种情况Java中不允许这样做。

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

根据您的问题进行简单扣除。

T是一种类型。

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

MyClass&lt; T&GT; extends T - MyClass是增强型T,但仅适用于Type T.

没有理由说明&#39;我扩展T但仅适用于T&#39;。

如果你扩展T,MyClass已经是T&amp;绝对不是X,Y或Z.

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