0

I've encoutered such issue, that android studio warns me about unreachable code. I don't understand, how it is unreachable.

My original code:

        try {
            return BasketProvider.valueOf(prefs.getString(KEY_BASKET_PROVIDER, null)) //unreachable code here
        } finally {
            return BasketProvider.LOCAL
        }

If I change finally to catch(e :IllegalArgumentException), there's no warning. If I combine all of them, the warning appears again.

        try {
            return BasketProvider.valueOf(prefs.getString(KEY_BASKET_PROVIDER, null))//no warning
        } catch (e: IllegalArgumentException) {
            return BasketProvider.LOCAL
        }
        --------------------------------
        try {
            return BasketProvider.valueOf(prefs.getString(KEY_BASKET_PROVIDER, null))//unreachable code
        } catch (e: IllegalArgumentException) {
            return BasketProvider.LOCAL //unreachable code
        } finally {
            return BasketProvider.LOCAL
        }

Is this a Kotlin bug, or am I missing something?

EDIT:

Basket provider is simple enum class:

enum class BasketProvider {
    LOCAL, SHARED
}
Marius Kaunietis
  • 674
  • 4
  • 17
  • 1
    You're not supposed to return from a finally block. Since a finally block is always run, what is return will supersede what is returned from the try or catch block, effectively making the return in the try or catch block unreachable, and swallowing exceptions thrown from the method. Don't return from the finally block: it's bad practice. A finally block is useful to always close resources, or do some other cleanup. – JB Nizet Nov 21 '16 at 09:31

1 Answers1

2

finally blocks always execute (unless you call System.exit() inbetween), so your return value in your finally block will always override your try/catch return values. See also: Does a finally block always run?

"Unreachable code" is misleading here, it should be called "return value is always overwritten by finally block".

Community
  • 1
  • 1
F. George
  • 4,970
  • 4
  • 20
  • 38
  • finally is `not always executed` in `kotlin`, you can use `suspendCoroutineOrReturn` in you try block, and return `COROUTINE_SUSPENDED` as the return value in your block thus to execute the try block without the finally block, the JB team says it's by design https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#resource-management-and-gc – Minami Mar 29 '18 at 12:32