Int::class.java.isInstance(4)
的结果是错误的。
但是String::class.java.isInstance("aa")
是真的。
Int
类型检查函数的正确方法是什么。
fun <T> castValue(v: Any?, clazz: Class<T>): T? {
if (v != null && clazz.isInstance(v) return v as T
return null
}
val result = castValue(4, Int::class.java)
答案 0 :(得分:2)
您可以使用reified
类型参数来实现此目的:
inline fun <reified T> cast(value:Any?): T? = value as? T
并称之为:
cast<Boolean>(false)
答案 1 :(得分:1)
::class.java
是调用Java方法而不是Kotlin。
如果要测试类型,请使用is
val isInt = 1 is Int // true
如果您想尝试演员,请使用as?
val num = unknown as? Int // null if it is not Int
答案 2 :(得分:0)
问题是Int::class
引用原始int
类型,但值是带框的Integer
类型。
解决方法是使用Integer::class
而不是Int::class
,因为这将引用盒装的Java类型。
为了更通用,您可以使用Apache Commons ClassUtils.primitiveToWrapper()
之类的帮助程序,或维护
fun primitiveToWrapper(clazz: Class<*>): Class<*> = when (clazz) {
java.lang.Void.TYPE -> java.lang.Void::class.java
java.lang.Boolean.TYPE -> java.lang.Boolean::class.java
java.lang.Byte.TYPE -> java.lang.Byte::class.java
java.lang.Character.TYPE -> java.lang.Character::class.java
java.lang.Short.TYPE -> java.lang.Short::class.java
java.lang.Integer.TYPE -> java.lang.Integer::class.java
java.lang.Long.TYPE -> java.lang.Long::class.java
java.lang.Float.TYPE -> java.lang.Float::class.java
java.lang.Double.TYPE -> java.lang.Double::class.java
else -> clazz
}
自己查找表。遗憾的是,Java或Kotlin中没有内置方法来获取基本类型的包装类。
@Suppress("UNCHECKED_CAST")
fun <T> castValue(v: Any?, clazz: Class<T>): T? =
v?.takeIf(primitiveToWrapper(clazz)::isInstance) as T?