基于提出的问题并回答here,我有一个更复杂的问题(至少在我看来)。为了使阅读(和回答)更容易,我将在此重述完整的代码示例:
让我们从定义一组类/接口开始:
public interface Node<NT extends Node<NT, ET>, ET extends Edge<NT, ET>> {
/* internal datastructures here */
}
public interface Edge<NT extends Node<NT, ET>, ET extends Edge<NT, ET>> {
/* internal datastructures here */
}
public interface Graph<NT extends Node<NT, ET>, ET extends Edge<NT, ET>> {
/* internal datastructures here */
}
public class JunctionNode implements Node<JunctionNode, RoadEdge> {
}
public class RoadEdge implements Edge<JunctionNode, RoadEdge> {
}
public class StreetGraph implements Graph<JunctionNode, RoadEdge> {
}
public class PTNode implements Node<PTNode, PTEdge> {
}
public class PTEdge implements Edge<PTNode, PTEdge> {
}
public class PTGraph implements Graph<PTNode, PTEdge> {
}
我现在需要定义一个多式联运图,即包含PTEdges和RoadEdges的图表。在我看来,我会通过陈述
来做到这一点public class IntermodalGraph implements Graph<Node, Edge> {
}
这里编译器对Node和Edge抱怨,因为Node被定义为有两个类型参数,其中一个是从第二个类型(这里是Edge)派生的。这意味着,我必须陈述
public class IntermodalGraph implements Graph<Node<Node, Edge>, Edge> {
}
到目前为止,第一个类型参数(Node)没问题,但第二个参数(Edge)失败,因为edge再次获取两个类型参数,第一个从Node派生。所以,我会写
public class IntermodalGraph implements Graph<Node<Node, Edge>, Edge<Node<Node, Edge>>, Edge> {
}
现在,第二个类型参数没问题,但第一个参数(显然)再次“坏”。
最后,我想实现一些像
这样的代码IntermodalGraph ig = new IntermodalGraph();
ig.add(new PTEdge());
ig.add(new RoadEdge());
Set<Edge> edges = ig.getEdges();
那么有人知道如何在保持类型安全的同时实现这一目标吗?
LG, 的Matthias
答案 0 :(得分:2)
由于您的课程已经指定了泛型,因此您可以将IntermodalGraph
课程声明为
public class IntermodalGraph<NT extends Node<NT, ET>, ET extends Edge<NT, ET>> implements Graph<NT, ET> {
}
这不应该发出任何警告。
** 编辑 **
你无法实现你想要的,即
IntermodalGraph ig = new IntermodalGraph();
ig.add(new PTEdge());
ig.add(new RoadEdge());
Set<Edge> edges = ig.getEdges();
除非添加unchecked
注释,否则不会抛出任何@SuppressWarnings("unchecked")
警告。但是,仍然是有效的Java语法并且可以工作;通用NT
默认为Node
,ET
为Edge
答案 1 :(得分:0)
正如toto已经指出的那样,你定义了一个类型可检查合同,然后继续打破它 - 并且编译器介入。类型安全的解决方案是简单地将合同分为两个,一个较弱且一个更严格的:一个Graph<N extends Node<?, ?>, E extends Edge<?, ?>>
接口以及StrictGraph<N extends Node<N, E>, E extends Edge<N, E>>
扩展Graph<N, E>
的接口。