如何在另一个有界类型上定义方法有界类型?

时间:2016-02-17 02:09:33

标签: java generics

我想定义一个定义其类型的方法:

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

2 个答案:

答案 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是类型参数

我看不出你如何能够强制执行这两个约束。