2017-04-10 93 views
2

让我们从一个代码示例开始,理想情况下,我希望可以这样做。Java泛型,在C <T extends MyClass <Z>>中,方法应返回Z

由于MyOtherClass是一个通用的

class MyOtherClass<Z>{} 

我想获得的MyOtherClass

class C<T extends MyOtherClass<Z>> { 
    Z myTypeOfReturnMethod() { return doStuff(); } 
} 

在Z不幸的是,据我知道,我不能指定,唯一有效的语法会be

class C<T extends MyOtherClass> { 
    ???MyOtherClass.Z??? myTypeOfReturnMethod() { return doStuff(); } 
} 

这样做的最好方法是什么? C可能有两种泛型,但它是重复性和容易出错的。

回答

3

“简单”的解决方案是通过明确引入它像这样讲述的附加型约束的Java:

class C<Z, T extends MyOtherClass<Z>> { 
    // ... 
} 

虽然这意味着一些人可以在你的typedeclarations感知为冗余的,至少你居然得到你想要的东西...

其他所有的东西在语义上都不被Java支持,主要是因为你在TypeBound of T中的Z不能作为Type参数(在JLS 8.1.2的意义上)被访问,但是TypeBound 。您想使用Z的地方还不知道Z,因为这并未作为类型参数清晰地引入并被清除。即使myTypeOfReturnMethod的签名更改为Object时也会发生编译错误,这一点尤其证明了这一点。其结果仍然是:

error: cannot find symbol 
    class C<T extends MyOtherClass<Z>> { 
           ^
symbol: class Z 

除了你最有可能真正想要的东西是什么“更冗余”(咳嗽),即:

class C<Z, T extends MyOtherClass<? extends Z>> { 

这实际上是由于在相当一些SO问题和JLS中列出的原因,与上面的非常不同...

+2

我不明白为什么这会是多余的。 – shmosel

+0

@shmosel调整公式并增加了一些信息;) – Vogel612

+3

仍然不认为它是非常多余的。我不会推荐'?扩展Z',除非明确指出'Z'是(仅)生产者,按[PECS](http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super)。 – shmosel

相关问题