在Kotlin中调用具有多个参数类型约束的泛型类型的方法

时间:2019-04-01 21:26:42

标签: java android generics kotlin interface

我有以下用Java编写的接口方法定义:

<T extends View & ISpecificView> T getSpecificView();

基于Java的使用者代码只需调用该方法就可以对该方法进行操作,并将返回值作为扩展View类并通过以下方式实现ISpecificView接口的对象来对待:< / p>

getContainer().getSpecificView().whateverTclassMethod()

尝试在Kotlin中调用相同的代码,我在Type inference failed: Not enough information to infer parameter T (...) Please specify it explicitly方法上遇到了getSpecificView()错误。 我想明确地提供类型,但是我无法传递任何特定的类,因为它可以是实现View接口的ISpecificView类的任何祖先。传递单个ViewISpecificView都无济于事-导致Type argument is not within its bounds. Expected: View! Found ICustomView,反之亦然。

在调用方法时,是否有可能在Kotlin中传递与Java的T extends View & ISpecificView等效的内容,以便我可以使用它?

2 个答案:

答案 0 :(得分:3)

回顾一下(我希望我的问题对了!),在Java中,您可以做到

final View view = getContainer().getSpecificView();  // or
final ISpecificView iview = getContainer().getSpecificView();

在科特林还是同一件事

val view: View = getContainer().getSpecificView()

得出Type inference failed: Not enough information to infer parameter T


经过50分钟的尝试...
只需创建一个虚拟class(抽象?)

abstract class KView : View(), ISpecificView

并使用它来显式设置通用返回类型

val view: View = getContainer().getSpecificView<KView>()
view.whateverClassMethod()

val iview: ISpecificView = getContainer().getSpecificView<KView>()
iview.whateverInterfaceMethod()

// or just

(getContainer().getSpecificView<KView>() as View).whateverClassMethod()
(getContainer().getSpecificView<KView>() as ISpecificView).whateverInterfaceMethod()

需要强制转换为ViewISpecificView,因为如果您这样做的话

getContainer().getSpecificView<KView>()

你会得到

class your.package$ExtendingClass cannot be cast to class your.package.KView

但这很好。
即使在Java中,您也需要决定要使用View还是ISpecificView


这样,您将可以对ViewISpecificView的所有方法进行操作。


真的,我不知道还能尝试什么。希望有人提出更好的建议。

编辑:如果您的意思是用Java,则可以

final ExtendedView ev = getContainer().getSpecificView();

好吧,即使编译了,这也是一个错误的恕我直言,因为您不能保证返回类型的确是ExtendedView。您只知道它可以扩展View并实现ISpecificView

答案 1 :(得分:0)

您应该可以使用以下方法实现此目标:

fun <T> getSpecificView() where T : View, T : ISSpecificView {}

有关此文档,请参见here