java - 嵌套 Java 泛型类型

标签 java generics

我正在尝试使用泛型实现图形,并且我想对节点和节点内的数据使用泛型参数。如果我用第一种方式来定义它,它会起作用,但理想情况下我想用第二种方式来定义它。

为什么第二种方法不起作用?

//OK
public class AdjacencyListGraph<E, N extends Node<E>> {
}

//Cannot resolve symbol E
public class AdjacencyListGraph<N extends Node<E>> {
}

最佳答案

在java泛型的上下文中,单词扩展表示上限边界,而不是继承。在泛型的情况下,这个词的含义是重载的。

Java 中引入泛型是为了让开发人员能够编写比以前更加一致、干净且错误更少的代码。一切都与开发有关,而不是执行。编译后的代码中没有泛型。但是,您可以通过反射检索有关元空间中实际类型的一些信息,但它是元信息,而不是实际代码。

在编译期间,泛型类型将被删除并替换为实际边界 ( https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html )。这是问题的根本原因。如果提供的边界也是通用的,则编译器无法执行类型删除。它只是不知道在编译期间应该用哪种类型替换代码中的通用类型。所以你会得到编译错误。

//OK
public class AdjacencyListGraph<E, N extends Node<E>> {
}

无论如何,在这里您必须提供实际类型 E,以便编译器能够解析实际绑定(bind)并执行类型删除。

//Cannot resolve symbol E
public class AdjacencyListGraph<N extends Node<E>> {
}

在这种情况下,你的界限也变得通用。编译器不知道实际类型。它可以是任何类型。因此它无法在这里执行类型删除并给出编译错误。

这里还有一些关于泛型的有用资源: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html https://docs.oracle.com/javase/tutorial/java/generics/index.html

第一张真的很棒。以下是有关扩展词的信息及其在泛型上下文中的含义:http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#Does%20extends%20always%20mean%20inheritance

关于java - 嵌套 Java 泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49943203/

相关文章:

java - 用于查找嵌套代码块的正则表达式

Java EE 应用程序数据库架构

java - Spring 的随机 Kerberos 验证错误

generics - 限制 Rust 结构体的泛型参数进行反序列化

java - 使用泛型作为参数

java - 在 Java 中将 BufferedImage 转换为 Mat (OpenCV)

java - 双向@OneToOne映射使用hibernate创建记录

c# - 'System.Int32' 类型的 ParameterExpression 不能用于 'System.String' 类型的委托(delegate)参数

c# - Lambda 表达式 : cast parameter to base type

java - 推理变量 T 具有不兼容的边界