我想定义一个定义其类型的方法:
List<R> toList(JsArray<T> array)
这样T的界限是:
T extends SomeClass
和T extends R
我尝试过这样的事情,但无济于事:
<R, T extends R & SomeClass> List<R> toList(JsArray<T> array)
(好奇,这是为了能够使用GWT Overlay Types with Interfaces)
答案 0 :(得分:2)
这个怎么样?
<T extends SomeClass> List<? super T> toList(JsArray<T> array)
编辑:
我想我看到了你的用例。从注释中,您需要指定返回类型,以便您没有未选中的强制转换。
但是你实际上没有传递任何信息来告诉方法要创建什么。因为我总是可以使用R = T
调用toList(),所以你可以做的唯一一件事(对于所有R super T
)是返回List<T>
,这使得R
参数不必要......但那不是你想要的。
你必须传入一些东西来告诉方法要实例化哪种对象。通常我们可以这样:
<R, T extends SomeClass> List<R> toList(JsArray<T> array, Class<R> cls)
并将其称为
toList(arrayIHave, WhatIWant.class)
现在这会有效,但你会抱怨它有错误条件,因为没有捕获“T extends R
”约束。但实际上,即使你添加约束,你仍然会有错误条件。
我可以通过R
扩展T
并实现SomeClass
,为R
使用任意接口。您无法有意义地实例化任意接口,因此对于满足约束的许多R,T
对,您将不得不返回null或抛出异常或其他内容。
毫无疑问,某些规则决定了你将返回哪个R,但是没有办法考虑指定捕获该规则的通用约束,因此将在某处进行未经检查的转换。如果您使用这样的签名,至少可以将其放在方法中,而不是在您使用它的任何地方都有警告或注释。
答案 1 :(得分:1)
我担心这不起作用。 正确的语法是
<R, T extends R & SomeClass> List<R> toList(JsArray<T> array)
但是这会给你以下错误信息
第一次绑定时,无法指定任何其他绑定SomeClass是类型参数
我看不出你如何能够强制执行这两个约束。