更广泛的递归/generics问题

基于这里提出和回答的问题,我有一个更复杂的问题(至少在我看来)。 为了使阅读(和回答)更容易,我将在此重述完整的代码示例:

让我们从定义一组类/接口开始:

public interface Node<NT extends Node, ET extends Edge> { /* internal datastructures here */ } public interface Edge<NT extends Node, ET extends Edge> { /* internal datastructures here */ } public interface Graph<NT extends Node, ET extends Edge> { /* internal datastructures here */ } public class JunctionNode implements Node { } public class RoadEdge implements Edge { } public class StreetGraph implements Graph { } public class PTNode implements Node { } public class PTEdge implements Edge { } public class PTGraph implements Graph { } 

我现在需要定义一个多式联运图,即包含PTEdges和RoadEdges的图。 在我看来,我会通过陈述来做到这一点

 public class IntermodalGraph implements Graph { } 

这里编译器对Node和Edge抱怨,因为Node被定义为有两个类型参数,其中一个是从第二个类型(这里是Edge)派生的。 这意味着,我必须说明

 public class IntermodalGraph implements Graph<Node, Edge> { } 

到目前为止,第一个类型参数(Node)没问题,但第二个参数(Edge)失败,因为edge再次获取两个类型参数,第一个参数派生自Node。 所以,我会写

 public class IntermodalGraph implements Graph<Node, Edge<Node>, Edge> { } 

现在,第二个类型参数是好的,但第一个参数(显然)再次“坏”。

最后,我想实现一些代码

 IntermodalGraph ig = new IntermodalGraph(); ig.add(new PTEdge()); ig.add(new RoadEdge()); Set edges = ig.getEdges(); 

那么有人知道如何在保持类型安全的同时实现这一目标吗?

lg,马蒂亚斯

由于您的类已经指定了generics,因此您可以将IntermodalGraph类声明为

 public class IntermodalGraph, ET extends Edge> implements Graph { } 

这不应该发出任何警告。

** 编辑 **

你不可能完成你想要的东西

 IntermodalGraph ig = new IntermodalGraph(); ig.add(new PTEdge()); ig.add(new RoadEdge()); Set edges = ig.getEdges(); 

除非添加@SuppressWarnings("unchecked")注释,否则不会抛出任何unchecked警告。 但是,它仍然是有效的Java语法并且可以工作; 通用NT将默认为NodeET to Edge

正如toto已经指出的那样,你定义了一个类型可检查合同,然后继续打破它 – 编译器介入。 一种类型安全的解决方案是简单地将合同分成两个,一个较弱和一个更严格的:一个Graph, E extends Edge>接口以及一个StrictGraph, E extends Edge>接口,扩展Graph