thông báo lỗi của bạn được rằng việc kiểm tra is
hy vọng một tên lớp và không phải là tham chiếu đến KClass ở bên phải. Bản thân thông điệp có thể hơi không rõ ràng. Nhưng điều tương tự cũng áp dụng trong Java, bạn sẽ không sử dụng toán tử instanceOf
mà thay vào đó, hãy gọi isAssignableFrom
.
Để được trợ giúp vào việc giải quyết vấn đề, bạn có ví dụ có thể được tìm thấy trong Github ...
Trong Klutter library là ví dụ về rất nhiều sự kết hợp của phong cách instanceof kiểm tra giữa Class
, KClass
, Type
và KType
như cũng như nguyên thủy. Bạn có thể sao chép ý tưởng từ đó. Có nhiều kết hợp mà bạn có thể muốn có trong thời gian dài.
Đây là mẫu lấy mẫu a big mix of extensions để kiểm tra xem một loại có thể gán cho loại kia hay không. Một vài ví dụ là:
fun <T : Any, O : Any> KClass<T>.isAssignableFrom(other: KClass<O>): Boolean {
if (this.java == other.java) return true
return this.java.isAssignableFrom(other.java)
}
fun <T : Any> KClass<T>.isAssignableFrom(other: Class<*>): Boolean {
if (this.java == other) return true
return this.java.isAssignableFrom(other)
}
fun KClass<*>.isAssignableFromOrSamePrimitive(other: KType): Boolean {
return (this.java as Type).isAssignableFromOrSamePrimitive(other.javaType)
}
fun KClass<*>.isAssignableFromOrSamePrimitive(other: Type): Boolean {
return (this.java as Type).isAssignableFromOrSamePrimitive(other)
}
fun Type.isAssignableFromOrSamePrimitive(other: Type): Boolean {
if (this == other) return true
if (this is Class<*>) {
if (other is Class<*>) {
return this == other.kotlin.javaObjectType || this == other.kotlin.javaPrimitiveType ||
this.isAssignableFrom(other)
}
return this.isAssignableFrom(other.erasedType())
}
return this.erasedType().isAssignableFrom(other.erasedType())
}
// ... and so on for every permutation of types
Xem linked source for all permutations.
Và bạn sẽ cần erasedType()
extension này được sử dụng bởi các mẫu trên - mà đi từ một Type
trở lại một Class
(sau khi loại chô bôi):
@Suppress("UNCHECKED_CAST") fun Type.erasedType(): Class<Any> {
return when (this) {
is Class<*> -> this as Class<Any>
is ParameterizedType -> this.getRawType().erasedType()
is GenericArrayType -> {
// getting the array type is a bit trickier
val elementType = this.getGenericComponentType().erasedType()
val testArray = java.lang.reflect.Array.newInstance(elementType, 0)
testArray.javaClass
}
is TypeVariable<*> -> {
// not sure yet
throw IllegalStateException("Not sure what to do here yet")
}
is WildcardType -> {
this.getUpperBounds()[0].erasedType()
}
else -> throw IllegalStateException("Should not get here.")
}
}
Nguồn
2016-09-21 23:55:04
Đồng nghiệp của tôi tìm thấy một SO bài mà nói Kotlin có không có cách nào để làm điều này và cách duy nhất là sử dụng sự phản chiếu Java (giả sử bạn đang nhắm mục tiêu JVM). http://stackoverflow.com/questions/35851719/how-to-compare-classes-and-interfaces/35852445#35852445 – zjuhasz