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

mrp*_*qal 5 java generics android interface kotlin

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

<T extends View & ISpecificView> T getSpecificView();
Run Code Online (Sandbox Code Playgroud)

基于 Java 的消费者代码能够简单地通过调用此方法来操作此方法,并将返回值视为扩展View类的对象,并ISpecificView通过以下方式实现接口:

getContainer().getSpecificView().whateverTclassMethod()
Run Code Online (Sandbox Code Playgroud)

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

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

Lpp*_*Edd 6

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

final View view = getContainer().getSpecificView();  // or
final ISpecificView iview = getContainer().getSpecificView();
Run Code Online (Sandbox Code Playgroud)

在 Kotlin 中同样的事情

val view: View = getContainer().getSpecificView()
Run Code Online (Sandbox Code Playgroud)

结果是 Type inference failed: Not enough information to infer parameter T


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

abstract class KView : View(), ISpecificView
Run Code Online (Sandbox Code Playgroud)

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

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()
Run Code Online (Sandbox Code Playgroud)

需要特定的强制转换为Viewor ISpecificView,因为如果你只是这样做

getContainer().getSpecificView<KView>()
Run Code Online (Sandbox Code Playgroud)

你会得到

class your.package$ExtendingClass cannot be cast to class your.package.KView
Run Code Online (Sandbox Code Playgroud)

但这完全没问题。
即使在 Java 中,您也需要决定是想要View一个ISpecificView.


这样,您就可以对View或 的所有方法进行操作ISpecificView


真的,我不知道还能尝试什么。希望有人想出更好的东西。

编辑:如果你的意思是在 Java 中,你会这样做

final ExtendedView ev = getContainer().getSpecificView();
Run Code Online (Sandbox Code Playgroud)

好吧,恕我直言,这有点错误,即使它可以编译,因为您不能保证返回类型真的是ExtendedView. 您只需确定它扩展View并实现ISpecificView.