2016-09-23 78 views
3

假设我有一些class Edge<A, B>与提供参数化的子类,如class MyEdge extends Edge<MyNodeType, MyOtherNodeType>Java泛型名称类型参数,而不需要它

我现在宣布使用另一个类Edge S作为这样:

class EdgeHolder<E extends Edge<A, B>, A, B> { 
    A getFirstNode(); 
    B getSecondNode(); 
} 

和使用它如下:

EdgeHolder<MyEdge, MyNodeType, MyOtherNodeType> var = ... 

这感觉非常笨重,特别是因为在MyEdge的定义中指定了和MyOtherNodeType

我很想能够参数A并在EdgeHolder定义B因为我需要编译时间上它的方法返回类型类型检查,但我不希望有当我声明EdgeHolder类型的变量时,指定AB

有没有办法做到这一点(或类似的东西)?

如果不是,为什么不呢?

+3

http://stackoverflow.com/questions/2382912/extract-generic-types-from-extended-generic – assylias

+0

为什么你首先需要EdgeHolder?为什么你要为每种特定类型需要EdgeHolder? – bashnesnos

+0

@bashnesnos我试图让问题中的示例尽可能简单,但实际上它实际上是多边的集合。 –

回答

3

Java中没有类型别名,但您可以尝试使用此方法。

class Edge<A, B> { 
    class MyEdgeHolder<E extends Edge<A, B>> extends EdgeHolder<E, A, B> {} 
} 
class MyEdge extends Edge<MyNodeType, MyOtherNodeType> { 
    class MyEdgeHolder extends Edge<MyNodeType, MyOtherNodeType>.MyEdgeHolder<MyEdge> {} 
} 

使用方法如下:

MyEdge.MyEdgeHolder var; 
Edge<?, ?>.MyEdgeHolder<?> var2 = var; 

这种做法是非常有限的,但可能适合您的具体方案。

+0

恩,谢谢。这只能部分缓解我的问题,因为我想随时传递一个'EdgeHolder'(不知道它是什么类型),我仍然需要做声明。这也意味着我会为每种可能的Edge类型定义'EdgeHolder'的子类,这有点不可行 –

+1

我略微扩展了我的想法。 – talex

+0

你的更新是完美的,并为我准备我需要的路径 - 谢谢! –

1

最好的办法我能来减少打字但保留类型在编译时检查:

class Edge<A, B> { 
    A src; 
    B dest; 
} 

class EdgeHolderBase<A, B, E extends Edge<A,B>> { 
    Edge<A,B> in_hold; 
} 

// explicit specialization of generics 
class MyEdge 
extends Edge<Integer, Long> { 

} 
class MyEdgeHolder 
extends EdgeHolderBase<Integer, Long, MyEdge> { 
// --- One off excessive typing --^

} 
+0

有效地与@ talex的答案相同,但有相同的缺点(只要你不知道你处理的是什么样的边缘,仍然必须声明'EdgeHolderBase ;必须为每种类型制作一个自定义持有者),但它确实有助于在一些地方清理代码。谢谢 –

+0

@ThomasShields assylas将一个很好的解释(在OP评论中)与你为什么不能做得比这更好相关。特别是,我喜欢[这个答案](http://stackoverflow.com/questions/2382912/extract-generic-types-from-extended-generic#answer-2401801) –