Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Kotlin-扩展泛型类并返回子类型时出现问题_Java_Kotlin_Generics_Hierarchy - Fatal编程技术网

Java Kotlin-扩展泛型类并返回子类型时出现问题

Java Kotlin-扩展泛型类并返回子类型时出现问题,java,kotlin,generics,hierarchy,Java,Kotlin,Generics,Hierarchy,我有以下情况: 抽象泛型类 抽象类K{ 抽象趣味绑定(itemModel:T) } 从K A类:K类{ 覆盖趣味绑定(itemModel:ModelA){ //…做任何事 } } B类:K{ 覆盖趣味绑定(itemModel:ModelB){ //…做任何事 } } 另一个类,这是一个工厂,它根据某个参数返回K的子类型: 类工厂{ 伴星{ const val TYPE_A:Int=0 const val TYPE_B:Int=1 趣味创作(类型:Int):K{ 返回时间(类型){

我有以下情况:

  • 抽象泛型类
抽象类K{
抽象趣味绑定(itemModel:T)
}
  • K
A类:K类{
覆盖趣味绑定(itemModel:ModelA){
//…做任何事
}
}
B类:K{
覆盖趣味绑定(itemModel:ModelB){
//…做任何事
}
}
  • 另一个类,这是一个工厂,它根据某个参数返回K的子类型:
类工厂{
伴星{
const val TYPE_A:Int=0
const val TYPE_B:Int=1
趣味创作(类型:Int):K{
返回时间(类型){
键入A->A()
类型_B->B()
}
}
}
}
此时,我在
Factory.create
方法的return-type部分得到一个错误,它说:“类K需要一个类型参数”。很明显,我试图在
create
方法中返回K的子类型,这是唯一重要的事情,而不是泛型的特定类型


这在Java中是可能的。科特林的正确方式是什么

这里有很多地方需要改进(根据评论更新)

  • 如果参数不是
    类型A
    类型B
  • 将*添加到参数化的K返回类型
结果会是这样的:

fun create(type: Int): K<*> {
   return when (type) {
       TYPE_A -> A()
       TYPE_B -> B()
       else -> throw IllegalStateException("useful message")
    }
}
fun create(类型:Int):K{
返回时间(类型){
键入A->A()
类型_B->B()
else->抛出IllegalStateException(“有用消息”)
}
}

这里有很多地方需要改进(根据评论更新)

  • 如果参数不是
    类型A
    类型B
  • 将*添加到参数化的K返回类型
结果会是这样的:

fun create(type: Int): K<*> {
   return when (type) {
       TYPE_A -> A()
       TYPE_B -> B()
       else -> throw IllegalStateException("useful message")
    }
}
fun create(类型:Int):K{
返回时间(类型){
键入A->A()
类型_B->B()
else->抛出IllegalStateException(“有用消息”)
}
}

问题在于
K
不是一个完整的类型,就像Java中不能返回
列表一样-必须返回
列表。因此,您需要说明这将返回一个
K
(或一些其他类型的绑定)

但是,现在您还有一个类型差异问题,因为
K
不是
K
的子类型,除非
K
的声明是
K
,但是您的
bind
方法在
in
位置有
T
,所以这是不可能的。这是有道理的,因为如果我给你一个调用
create
的结果,你就无法知道你可以传递给
bind
什么类型的东西,所以它没有那么有用


如前一个回复中所述,您可以创建return
K
,这将进行编译,但我不确定这是否有用,因为您必须知道实际的类型才能调用
bind
——也就是说,您必须强制转换任何
create
返回,在这种情况下,您可能只需构造特定于类型的首先。

问题是
K
不是一个完整的类型,就像Java中不能返回
列表一样-必须返回
列表。因此,您需要说明这将返回一个
K
(或一些其他类型的绑定)

但是,现在您还有一个类型差异问题,因为
K
不是
K
的子类型,除非
K
的声明是
K
,但是您的
bind
方法在
in
位置有
T
,所以这是不可能的。这是有道理的,因为如果我给你一个调用
create
的结果,你就无法知道你可以传递给
bind
什么类型的东西,所以它没有那么有用


如前一个回复中所述,您可以创建return
K
,这将进行编译,但我不确定这是否有用,因为您必须知道实际的类型才能调用
bind
——也就是说,您必须强制转换任何
create
返回,在这种情况下,您可能只需构造特定于类型的首先。

您可以通过返回
K
来编译它,但是您将无法对返回的实例执行太多操作。在Java中,可以通过忽略编译器警告来处理原始类型,并在开始尝试调用返回对象上的方法时冒ClassCastException的风险,但是为什么要使用泛型呢

相反,您可以使用具体化类型,以便调用方可以传递生成的实例可以处理的类型,而不是某个数字:

    @Suppress("UNCHECKED_CAST")
    inline fun <reified T> create(): K<T> {
        return when (T::class) {
            ModelA::class -> A()
            ModelB::class -> B()
            else -> error("unsupported type")
        } as K<T>
    }
@Suppress(“未选中的\u CAST”)
inline fun create():K{
返回时间(T::class){
ModelA::class->A()
ModelB::class->B()
else->错误(“不支持的类型”)
}作为K
}

您可以通过返回
K
来编译它,但是您将无法对返回的实例执行太多操作。在Java中,可以通过忽略编译器警告来处理原始类型,并在开始尝试调用返回对象上的方法时冒ClassCastException的风险,但是为什么要使用泛型呢

相反,您可以使用具体化类型,以便调用方可以传递生成的实例可以处理的类型,而不是某个数字:

    @Suppress("UNCHECKED_CAST")
    inline fun <reified T> create(): K<T> {
        return when (T::class) {
            ModelA::class -> A()
            ModelB::class -> B()
            else -> error("unsupported type")
        } as K<T>
    }
@Suppress(“未选中的\u CAST”)
inline fun create():K{
返回时间(T::class){
ModelA::class->A()
ModelB::class->B()
else->错误(“不支持的类型”)
}作为K
}