有没有一种方法可以指定嵌套泛型,而无需在Java 8+中指定两次类型

时间:2016-08-05 16:26:18

标签: java generics

鉴于以下示例......

S表示ConcreteType A的起始节点

T表示ConcreteType B的结束节点

E表示边缘,其中S为起始节点,T为末端节点

EdgeSet有一组由接口方法

访问的边

SomeObject o通过SomeObject.getEdges();

方法返回EdgeSet接口

使用泛型定义的类定义如下......

    public class EdgeSet<S extends Node, T extends Node, E extends Edge<S, T>> { ... }

    public class SomeObject {

      protected EdgeSet<ConcreteNodeA, ConcreteNodeB, ConcreteEdge<ConcreteNodeA, ConcreteNodeB>> someEdgeSet;

      ...

      public EdgeSet<? extends ConcreteNodeA, ? extends ConcreteNodeB, ? extends ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>> getEdges() { 
        //returns someEdgeSet... 
      }
    }

用法示例......

    EdgeSet<? extends ConcreteNodeA, ? extends ConcreteNodeB, ? extends ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>> exampleEdgeSet = o.getEdges();

是否有某种方法可以定义此代码,以及使用成员方法而无需定义两次的代码?

例如:

public class EdgeSet<E extends Edge<S extends Node, T extends Node>> { ... }

EdgeSet<ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>>

protected EdgeSet<ConcreteEdge<ConcreteNodeA, ConcreteNodeB>>

如果没有,是否有可以通过RFC来减少冗余信息的地方?

1 个答案:

答案 0 :(得分:1)

  

是否有某种方法可以定义此代码,以及使用成员方法而无需定义两次的代码?

根据您当前定义的<doc><str name="_uniqueid">sitecore://web/{1830d10d-bb75-48ee-91f6-5fec6dfabea9}?lang=en&ver=1</str></doc> <doc><str name="_uniqueid">sitecore://web/{1830d10d-bb75-48ee-91f6-5fec6dfabea9}?lang=en&ver=2</str></doc> ,我看到的唯一选择是使用非通用的<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script> <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" /> <script type="text/javascript"> $(function () { $('#tabs').tab(); $("#btnGoToTab2").click(function () { $('#tabs a[href="#tabTwo"]').tab('show') }); $("#btnGoToTab1").click(function () { $('#tabs a[href="#tabOne"]').tab('show') }); }); </script> <div id="content"> <ul id="tabs" class="nav nav-tabs" data-tabs="tabs"> <li><a href="#tabOne" data-toggle="tab">Tab One</a></li> <li><a href="#tabTwo" data-toggle="tab">Tab Two</a></li> </ul> <div id="my-tab-content" class="tab-content"> <div class="tab-pane active" id="tabOne"> <h1>Tab One</h1> <input id="btnGoToTab2" type="button" value="Go To Tab 2" /> </div> <div class="tab-pane" id="tabTwo"> <h1>Tab Two</h1> <input id="btnGoToTab1" type="button" value="Back To Tab 1" /> </div> </div> </div> 实现:

EdgeSet

然后你可以编写诸如

之类的声明
Edge

但仍有一些冗余,因为public class ConcreteEdgeAB extends Edge<ConcreteNodeA, ConcreteNodeB> { // ... } protected EdgeSet<ConcreteNodeA, ConcreteNodeB, ConcreteEdgeAB> someEdgeSet; ConcreteNodeAConcreteNodeB使用STConcreteEdgeAB的唯一类型为E。而且,你可能不会那么灵活。

我倾向于认为主要问题是你过度参数化了。如果您的Edge类型本身通过其末端的节点类型进行参数化,那么在节点类型上参数化一组边缘本身也是多余的 - 需要 edge 集合仅在其包含的边缘类型上进行参数化:

interface Edge<S extends Node, T extends Node> {
}

// The bounds on the type parameters of Edge effectively apply here, too:
public class EdgeSet <E extends Edge<?, ?>> {
    // ...
}

public class SomeObject {

    protected EdgeSet<ConcreteEdge<ConcreteNodeA, ConcreteNodeB>> someEdgeSet;

    ...

    public EdgeSet<? extends ConcreteEdge<? extends ConcreteNodeA, ? extends ConcreteNodeB>> getEdges() { 
        return someEdgeSet;
    }
}