Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting "Callable<T>" Java method to Kotlin

Tags:

kotlin

I'm trying to convert a Java method:

private <T> Callable<T> createCallable(final Callable<T> task) {
    return () -> {
        try {
            return task.call();
        } catch (Exception e) {
            handle(e);
            throw e;
        }
    };
}

from the following Java file ExceptionHandlingAsyncTaskExecutor.java into Kotlin.

The code gets converted automatically using IntelliJ IDEA into:

private fun <T> createCallable(task: Callable<T>): Callable<T> {
    return {
        try {
            return task.call()
        } catch (e: Exception) {
            handle(e)
            throw e
        }
    }
}

which is not correct. But I have to idea what the correct implementation for this should be. Any ideas?

like image 746
Jerry Avatar asked Jul 26 '17 00:07

Jerry


2 Answers

I think this is an Kotlin converter bug. It converted your code to () -> T instead of Callable<T> (which is basically the same but these are actually different types). This is the working code

private fun <T> createCallable(task: Callable<T>): Callable<T> {
    return Callable {
        try {
            task.call()
        } catch (e: Exception) {
            handle(e)
            throw e
        }
    }
}
like image 60
Mibac Avatar answered Sep 29 '22 15:09

Mibac


This is how I did it, might be too verbose, but it works. I also implement a handle function.

import java.util.concurrent.*

private fun <T> createCallable(task: Callable<T>): Callable<T> {
    return object : Callable<T> {
    override fun call(): T  {
            try {
                return task.call()
            } catch (e: Exception) {
                handle(e)
                throw e
            }
        }
    }
}

private fun handle(e: Exception): Unit { println("got exception") }

And this how I call it in a test...

fun main(vararg argv: String): Unit {
    val callable1 = object : Callable<Int> {
        override fun call(): Int = 1
    }
    val c1 = createCallable(callable1)
    println("callable1 = ${c1.call()}")

    val callable2 = object : Callable<Unit> {
        override fun call(): Unit { println("Hello"); throw Exception("Hello") }
    }
    val c2 = createCallable(callable2)
    c2.call()
}
like image 39
Les Avatar answered Sep 29 '22 16:09

Les