我正在尝试使用泛型实现图形,并且我想对节点和节点内的数据使用泛型参数。如果我用第一种方式来定义它,它会起作用,但理想情况下我想用第二种方式来定义它。
为什么第二种方法不起作用?
//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/