我有一个Java对象,它有方法 getLong
, getBoolean
和 getString
. 我试图创建一个具有函数作为最后一个参数的通用扩展函数 . 基本上包装try和catch并调用可能引发异常的 getString
等 . 我发现调用例如 getIt<Long>() { // do something with it }
时设置的 <reified T>
需要反射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)
}
}
因此,除了布尔问题之外,我想通过使用 T
来调用正确的get类型 . 我遇到需要将kaitlin反射jar添加到类路径中 . 我希望尽可能避免这种情况 .
UPDATE1:使用 when
与 T::class
的第一个答案和响应实际上不起作用 . 谢谢你的想法,它帮我看了一遍 . 第二个我找到"wordier"比我想要的,所以我最终得到了这个解决方案 .
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", JSONObject::getString) { err = it }
相比,这看起来像 jsonObj.getIt<String>("error") { er = it }
更新2:这似乎最终是一种更好的方法,至少对我而言,避免了使用泛型来实现目标的问题
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") }
1 回答
kotlin
is
运算符在左侧获取一个对象,在右侧获取一个类引用 . 您可以在那里使用简单的相等检查,因为您已经在两侧都有类引用 .T在编译时仍然是未知的,所以考虑
this.get*() as T
不会't make a whole lot of sense. You'll已经验证了你的块中的类型,所以你也可以使用它 .作为完整性问题,您可能还希望包含一个else块,以防有人调用
jsonObject.getIt<Date>(...)
.我还包括了第二个版本,它需要一个额外的参数来调用,但听起来像你原本想要的一个不那么冗长的版本 . 它需要
key
,accessor
和block
,并且可以在将来添加到JSONObject
的任何现有和新访问器上工作,而无需对扩展进行任何修改或修改 .