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 代码(假设 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<Int32>
时需要 Class<Message>
,并且 Class
在 T
中不是协变的。为了编译该代码,您可以执行以下操作:
fun doSomethingWithType(type: Class<out Message>) { ... }
doSomethingWithType(Int32::class.java)
只要您只从 Class<T>
中取出 T
,这就会起作用,即 Class
只会产生类型 T
.
我发现在 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 代码(假设 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<Int32>
时需要 Class<Message>
,并且 Class
在 T
中不是协变的。为了编译该代码,您可以执行以下操作:
fun doSomethingWithType(type: Class<out Message>) { ... }
doSomethingWithType(Int32::class.java)
只要您只从 Class<T>
中取出 T
,这就会起作用,即 Class
只会产生类型 T
.