How to compare classes and interfaces?
11,706
Kotlin reflection doesn't have an API for retrieving information about KClass
hierarchy, so the only way to check if one KClass
is superclass or subclass of another KClass
is to compare corresponding java classes:
interface IB {}
interface IC : IB {}
open class A {}
open class B : A() {}
open class C : B(), IC {}
fun main(args: Array<String>) {
if (B::class == B::class) { println("B class is equal to B class") }
if (IB::class == IB::class) { println("IB interface is equal to IB interface") }
if (A::class.java.isAssignableFrom(B::class.java)) { println("A class is parent of B class") }
if (A::class.java.isAssignableFrom(C::class.java)) { println("A class is superclass of C class") }
if (IC::class.java.isAssignableFrom(C::class.java)) { println("C class implements IC interface") }
if (IB::class.java.isAssignableFrom(IC::class.java)) { println("IC interface implements IB interface") }
}
UPDATE: You can also define two extension functions that will make this kind of checks a bit nicer:
inline fun <reified L : Any, reified R : Any> isSubClassOf(): Boolean {
return R::class.java.isAssignableFrom(L::class.java)
}
inline fun <reified L : Any, reified R : Any> isSuperClassOf(): Boolean {
return L::class.java.isAssignableFrom(R::class.java)
}
fun main(args: Array<String>) {
if (isSubClassOf<B, B>()) { println("B class is equal to B class") }
if (isSubClassOf<IB, IB>()) { println("IB interface is equal to IB interface") }
if (isSuperClassOf<A, B>()) { println("A class is parent of B class") }
if (isSuperClassOf<A, C>()) { println("A class is superclass of C class") }
if (isSubClassOf<C, IC>()) { println("C class implements IC interface") }
if (isSubClassOf<IC, IB>()) { println("IC interface implements IB interface") }
}
Comments
-
Maxim almost 2 years
Can anybody explain me how to compare
KClass
es and interfaces among themselves? I know how to check if classes or interfaces are equal but I don't understand how to check if A class is a superclass of B class, etc.interface IB {} interface IC : IB {} open class A {} open class B : A() {} open class C : B(), IC {} fun main(args: Array<String>) { if (B::class == B::class) { println("B class is equal to B class") } if (IB::class == IB::class) { println("IB interface is equal to IB interface") } if (A::class ??? B::class) { println("A class is parent of B class") } if (A::class ??? C::class) { println("A class is superclass of C class") } if (C::class ??? IC) { println("C class implements IC interface") } if (IC ??? IB) { println("IC interface implements IB interface") } }
-
voddan about 8 yearswow, I would expect
compareTo
operator to be overloaded for that -
Vladimir Mironov about 8 years@voddan you can not define a
compareTo
operator for partially ordered sets -
Maxim about 8 years@VladimirMironov I think @voddan mean something like this. As you can see possible to override
compareTo
and use<
,>
,<=
,>=
operators for compare classes (for example such syntax using in Ruby). I hope kotlin.reflect will have something like this in the future. -
Vladimir Mironov about 8 years@maxd stdlib will never have such operator because it's just impossible to properly implement
compareTo
forKClass
. Your implementation violatescompareTo
contract, because it should never throw. -
voddan about 8 years@VladimirMironov this contract to never throw out of
compareTo
exists in Java, but does not in Kotlin (no checked exceptions as a concept). I think the implementation mentioned by @maxd makes sense and violates nothing since it is invisible from Java -
Nikola Mihajlović about 6 yearsThere are extensions: isSuperclassOf isSubclassOf. So there is no need to define your own. Make sure to include
kotlin-reflect
library though