关于Kotlin中Int :: class.java.isInstance()的一个混淆

Int::class.java.isInstance(4)是false。

但是String::class.java.isInstance("aa")是真的。

在这样的函数中, Inttypes检查的正确方法是什么?

 fun  castValue(v: Any?, clazz: Class): T? { if (v != null && clazz.isInstance(v) return v as T return null } val result = castValue(4, Int::class.java) 

你可以使用reifiedtypes参数来实现这个function:

 inline fun  cast(value:Any?): T? = value as? T 

并像这样调用它:

cast(false)

::class.java是调用Java方法而不是Kotlin。

如果你想测试的types,使用is

 val isInt = 1 is Int // true 

如果你想尝试演员,使用as?

 val num = unknown as? Int // null if it is not Int 

问题是, Int::class引用了原始的inttypes,但是值是盒装的Integertypes。

解决方法是使用Integer::class而不是Int::class ,因为这将引用盒装的Javatypes。

为了更通用,你可以使用像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没有内置的方法来获取原始types的包装类。

 @Suppress("UNCHECKED_CAST") fun  castValue(v: Any?, clazz: Class): T? = v?.takeIf(primitiveToWrapper(clazz)::isInstance) as T?