Is there any way to get a "safe" `is` check on Kot...
# getting-started
Is there any way to get a "safe"
check on Kotlin/JVM, in the sense that it doesn't fail with
if the class is not on the classpath? I would like to do something with an object if it's of a given type, with the smart cast, but I don't want it to fail if running on lower JDK that doesn't have that class, I just want the condition to be false, and the code to move on without trying to load the class.
I'm currently juggling with the fqn of the class,
and unsafe casts, but I wish there was something baked in
My current use case is about extracting information from an exception, and I have a
that handles different types of exceptions. One of them only exists on JDK11+ and the
is now failing on Android target because of the missing class
Just a thought:
Copy code
catch (e: Exception) {
    when {
        ClassLoader.getSystemResource("java/lang/whatever/ThisParticularException.class") != null
            && e is ThisParticularException -> TODO()
Yes that's along the lines of what I'm doing now, but using
with try/catch instead
My latest attempt looks like this:
Copy code
private inline fun <reified C : Any> Any.safeIs(className: String): Boolean {
    contract {
        returns(true) implies(this@safeIs is C)
    if (!classExists(className)) {
        return false
    checkMatches<C>(className) // prevent developer mistakes
    return this is C

private inline fun <reified T : Any> checkMatches(className: String) {
    val typeName = T::class.qualifiedName
    require(typeName == className) {
        "Mismatch between the given class name '$className' and the actual parameter type of the action lambda '$typeName"

private fun classExists(className: String): Boolean = try {
} catch (e: ClassNotFoundException) {
So I can have nice usages like:
Copy code
if (obj.safeIs<HttpClient>("")) {
    // obj is smart-cast to HttpClient here
Which also includes a check that the fqn and the type param actually match
when is implemented, perhaps it will be possible for
to be inlined as a compile-time constant
this requires more overhead but in general I'd rather split stuff using potentially-unavailable classes into classes of their own, and use reflection to load those wrappers, instead of using reflection on third-party classes directly
Copy code
internal interface Foo {
    fun isHttpClient(value: Any): Boolean
internal class Java11Foo {
    fun isHttpClient(value: Any): Boolean = value is HttpClient
fun isHttpClient(value: Any): Boolean {
    val iterator = ServiceLoader.load(
    while (iterator.hasNext()) {
        try {
        } catch (_: NoClassDefFoundError) {
            // continue
    return false

// META-INF/services/Foo