I have a Java object that has methods getLong
, getBoolean
and getString
. I attempted to make a generic extension function that has a function as the last parameter. Essentially wrapping the try and catch and call to getString
etc that could throw an exception. I discovered that <reified T>
as set when calling for example getIt<Long>() { // do something with it }
needs the reflection api to figure out T
. I could not do is check nor isInstance. Any ideas?
// This is the non generic function version to get an idea
inline fun JSONObject.getItLong(key: String, block: (value: Long) -> Unit) {
try {
block(this.getLong(key))
} catch (e: JSONException) {
Log.w("${ javaClass.simpleName }KEx", e.message)
}
}
The below when
does not work.
inline fun <reified T> JSONObject.getIt(key: String, block: (value: T) -> Unit) {
try {
when {
Long is T -> { block(this.getLong(key) as T) }
String is T -> { block(this.getString(key) as T) }
// Boolean is T -> { block(this.getBoolean(key) as T) } // Boolean broken, does not have companion object?
}
} catch (e: JSONException) {
Log.w("fetchFromJSONObject", e.message)
}
}
So, aside from the Boolean issue I wanted to have a generic way to call the right type of get by using T
. I ran into needing to add kaitlin reflection jar to the classpath. I wanted to avoid that if possible.
UPDATE1: The first answer and response using a when
with T::class
does not actually work. Thanks for the idea and it helped me look again. The second I found "wordier" than what I wanted, so I ended up with this solution.
inline fun <reified T> JSONObject.getIt(key: String, block: (value: T) -> Unit) {
try {
block(this.get(key) as T)
} catch (e: JSONException) {
Log.w("${ javaClass.simpleName }KEx", e.message)
}
}
This looks like this jsonObj.getIt<String>("error") { er = it }
as compared to jsonObj.getIt<String>("error", JSONObject::getString) { err = it }
UPDATE2: This seems like ultimately a better approach, at least for me and avoids the issues with working with generics to meet the goal
inline fun JSONObject.unless(func: JSONObject.() -> Unit) {
try {
this.func()
} catch (e: JSONException) {
Log.w("${ javaClass.simpleName }KEx", e.message)
}
}
Using:
jsonObj.unless {
sDelay = getLong("s_delay") * 1000
wDelay = getLong("w_delay") * 1000
}
jsonObj.unless { sam = getBoolean("sam") }
jsonObj.unless { err = getString("error") }