Java Kotlin泛型使用通配符自定义类型

Java Kotlin泛型使用通配符自定义类型,java,generics,kotlin,Java,Generics,Kotlin,因此,在Java中,我可以执行以下操作,定义一个具有超类和接口约束的类型 public class Main<ControllerType extends Node & Controller> { private ControllerType controller; private ControllerType controller2; private Main(ControllerType controller, ControllerType co

因此,在Java中,我可以执行以下操作,定义一个具有超类和接口约束的类型

public class Main<ControllerType extends Node & Controller> {
    private ControllerType controller;
    private ControllerType controller2;

    private Main(ControllerType controller, ControllerType controller2) {
        this.controller = controller;
        this.controller2 = controller2;
    }

    public static void main(String[] args) {
        Main<?> main = new Main<>(new Home(), new Parent());
    }
}
公共类主{
专用控制器类型控制器;
专用控制器类型控制器2;
专用干管(控制器类型控制器、控制器类型控制器2){
this.controller=控制器;
this.controller2=controller2;
}
公共静态void main(字符串[]args){
Main Main=newmain(newhome(),newparent());
}
}
但在科特林,这是不可能的

class Main<ControllerType>(val controller: ControllerType, val controller2: ControllerType)
        where ControllerType : Node, ControllerType : Controller

fun main(args: Array<String>) {
    val main = Main<*>(Home(), Parent())
}
class Main(val控制器:ControllerType,val控制器2:ControllerType)
其中ControllerType:Node,ControllerType:Controller
趣味主线(args:Array){
val main=main(Home(),Parent())
}
我在星体投影上得到以下错误:

不允许对函数和属性的类型参数进行投影


那么,如何解决这个问题呢。我研究了类型别名,但它们没有我想要的功能。

不,没有办法像Java一样使用通配符。这是不可能的,因为通配符不安全

private Main(ControllerType controller, ControllerType controller2)
controller
controller2
被假定为相同或继承的类型,但Java允许您使用通配符将其隐藏

星体投影不是通配符替换。当您不知道确切的类型并允许您执行安全操作时,可以使用星形投影

如果
controller
controller2
是两种不同的类型,那么您应该有两个通用参数

class Main<T, U>(val controller: T, val controller2: U)
        where T : Node, T : Controller, U : Node, U : Controller

fun main(args: Array<String>) {
    val main = Main(Home(), Parent())
}
主类(val控制器:T,val控制器2:U)
其中T:Node,T:Controller,U:Node,U:Controller
趣味主线(args:Array){
val main=main(Home(),Parent())
}

该错误完全是由于试图在实例创建表达式中使用通配符(投影)造成的。它与交叉口类型或Kotlin无关

在声明中

Main<?> main = new Main<>(new Home(), new Parent());
Main Main=newmain(newhome(),newparent());
不是
,而是

在科特林,同样的说法是

val main : Main<*> = Main<Node>(Home(), Parent())
val main:main=main(Home(),Parent())
或(不带显式类型参数)

val main:main=main(Home(),Parent())

我认为使用通配符是安全的,因为
controller
controller2
有一个满足约束条件的通用类型:至少
节点和控制器
。Java只允许在很少的上下文中编写交集类型,这不是其中之一,但它们仍然存在并可以推断。
val main : Main<*> = Main(Home(), Parent())