首页 > 解决方案 > Java 类定义的类型推断失败。我该如何解决这个问题?

问题描述

在 Kotlin 中,我发现与 Java 相比,可以使用covariance完成以下操作:

ArrayList<Dog> listOfDogs = listOf(dog1, dog2)
ArrayList<Animal> animalList = listOfDogs // No compiler error

在我的情况下,我有一个界面消息:

public interface Message {
     RawMessage toRawMessage();
}

例如我有一条Int32消息:

public interface Int32 extends Message {
    // abstract methods
} 

现在我有一个带有type类型参数的方法Class<Message>

fun doSomethingWithType(type: Class<Message>) {
    // Implementation
}

问题是我试图传递一个从 Message 扩展的 Java 类,例如:

doSomethingWithType(Int32::class.java)

但这给了我以下编译器错误:

Expected type mismatch: 
required: Class<Message> 
found:    Class<Int32>

为什么这不起作用,我应该如何解决?

标签: javakotlinabstract-classcovariance

解决方案


以下是有效的 Kotlin 代码(假设Dog是 的子类Animal):

val listOfDogs: List<Dog> = listOf(dog1, dog2)
val listOfAnimals: List<Animal> = listOfDogs

这背后的原因List是 Kotlin 接口定义为:

public interface List<out E> : Collection<E>

不幸的是,你不能在纯 Java 中做同样的事情,但你可以这样做:

List<Dog> listOfDogs = new ArrayList<>();
List<? extends Animal> listOfAnimals = listOfDogs;

现在,doSomethingWithType期望Class<Message>您提供一段时间Class<Int32>,并且ClassT. 为了使该代码编译,您可以执行以下操作:

fun doSomethingWithType(type: Class<out Message>) { ... }
doSomethingWithType(Int32::class.java)

只要您只T从中拉出Class<T>,即Class只会产生 type ,这将起作用T


推荐阅读