Java class 定义的类型推断失败。我该如何解决这个问题?

Type inference failed for a Java class definition. How can I solve this?

我发现在 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
}

问题是我试图传递一个 Java class 扩展自 Message ,例如:

doSomethingWithType(Int32::class.java)

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

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

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

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

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<Int32> 时需要 Class<Message>,并且 ClassT 中不是协变的。为了编译该代码,您可以执行以下操作:

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

只要您只从 Class<T> 中取出 T,这就会起作用,即 Class 只会产生类型 T.