在Kotlin可以进行交叉铸造吗?

All*_*n W 12 casting type-inference kotlin

我有一个Java方法,如下所示:

public <T extends A & B> methodName(T arg, ...)
Run Code Online (Sandbox Code Playgroud)

其中A是类,B是接口.

在我的kotlin类中,我有另一个variable类型C,我希望实现以下目标:

if (variable is A && variable is B) {
    methodName(variable, ...)
} else {
    // do something else
}
Run Code Online (Sandbox Code Playgroud)

是否可以正确投射,variable以便它可以作为参数使用而不会出错?

目前,variable有一个setter方法,因此没有智能铸造.但是,我还使用本地测试了它,val并且推断出值具有Any无效的类型.

mar*_*ran 9

Kotlin不支持交叉类型.这将导致variable要聪明投地Any,因为这是共同的祖先AB.

但是,Kotlin确实支持泛型类型约束.您可以使用它将类型参数约束为一种或多种类型.这可以在方法和类上使用.这是函数的语法(相当于你methodName在Kotlin中的函数):

fun <T> methodName(arg: T)
    where T : A,
          T : B {
    ....
}
Run Code Online (Sandbox Code Playgroud)

您可以使用此通过创建同时扩展一个类来解决你的问题A,并B,然后代表这些类型的实现你的目标.像这样:

class AandB<T>(val t: T) : A by t, B by t
    where T : A,
          T : B
Run Code Online (Sandbox Code Playgroud)

您现在可以methodName通过更改if-test来检查它是否是AandB<*>:

if (variable is AandB<*>) {
    methodName(variable, ...)
}
Run Code Online (Sandbox Code Playgroud)

你确实需要variableAandB某个地方包装.如果你没有variable任何地方可用的类型信息,我认为你不能这样做.

注意:AandB该类未实现hashCode,equalstoString.你可以实现它们来委托t实现.

注2:这仅适用于如果AB是接口.你不能委托给一个班级.