我有一个具有方法的 Java 对象getLong
,getBoolean
并且getString
. 我试图制作一个通用扩展函数,它有一个函数作为最后一个参数。getString
本质上包装了可能引发异常的尝试、捕获和调用等。我发现,<reified T>
例如调用时设置的getIt<Long>() { // do something with it }
需要反射 api 来弄清楚T
。我不能做的是检查,也不能做isInstance。有任何想法吗?
// 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)
}
}
以下when
不起作用。
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)
}
}
因此,除了布尔问题之外,我还希望有一种通用的方式来调用正确类型的 get 通过使用T
. 我遇到需要将 kaitlin 反射 jar 添加到类路径中。如果可能的话,我想避免这种情况。
UPDATE1:使用when
with的第一个答案和响应T::class
实际上不起作用。感谢您的想法,它帮助我重新审视。第二个我发现比我想要的更“冗长”,所以我最终得到了这个解决方案。
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)
}
}
这看起来像jsonObj.getIt<String>("error") { er = it }
这样jsonObj.getIt<String>("error", JSONObject::getString) { err = it }
UPDATE2:这似乎最终是一种更好的方法,至少对我而言,并且避免了使用泛型来实现目标的问题
inline fun JSONObject.unless(func: JSONObject.() -> Unit) {
try {
this.func()
} catch (e: JSONException) {
Log.w("${ javaClass.simpleName }KEx", e.message)
}
}
使用:
jsonObj.unless {
sDelay = getLong("s_delay") * 1000
wDelay = getLong("w_delay") * 1000
}
jsonObj.unless { sam = getBoolean("sam") }
jsonObj.unless { err = getString("error") }