使用kotlin reflect设置可为空的UShort
为什么我不能在kotlin中使用反射设置UShort?我将问题提取到单元测试中 我的测试如下所示:使用kotlin reflect设置可为空的UShort,kotlin,kotlin-reflect,Kotlin,Kotlin Reflect,为什么我不能在kotlin中使用反射设置UShort?我将问题提取到单元测试中 我的测试如下所示: 类垃圾{ 变量DA:UShort?=null } 课堂测试{ @试验 有趣的testSetShort(){ var uut=Junk() val值=100 预期值=100 val属性:集合=垃圾::class.memberProperties val property=properties.find{property->property.name==“DA”} if(属性为KMutableProp
类垃圾{
变量DA:UShort?=null
}
课堂测试{
@试验
有趣的testSetShort(){
var uut=Junk()
val值=100
预期值=100
val属性:集合=垃圾::class.memberProperties
val property=properties.find{property->property.name==“DA”}
if(属性为KMutableProperty){
property.setter.call(uut,value.toUShort())/*在此失败*/
}
资产质量(预计,uut.DA)
System.err.println(“ok”)
}
}
结果是
argument type mismatch
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:97)
at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Instance.call(CallerImpl.kt:113)
at kotlin.reflect.jvm.internal.calls.InlineClassAwareCaller.call(InlineClassAwareCaller.kt:142)
at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:108)
at Tests.testSetShort(testSetUshort.kt:24)
我尝试过的事情:
- 强制值的类型为UShort?在这种情况下,可空性是问题所在(尽管当我尝试对可空字符串var执行相同操作时,这不是问题)
- 内联类存在问题。正如您所知,内联类仍然是实验性的,
UShort
是一个内联类,它充当Short
的包装器:
public inline class UShort @PublishedApi internal constructor(@PublishedApi internal val data: Short) : Comparable<UShort>
正如您所知,内联类应该在编译后被忽略和删除,但由于您将DA
定义为可空,编译后的类型仍然是UShort
,而不是Short
但是,当您在对象上调用Int.toUShort
时,编译后的代码没有UShort
的符号,而是转换为Short
(因为它是一个内联类,所以应该如此)。这就是为什么会出现参数类型不匹配
错误的原因。因为setter需要一个UShort
,但您给它一个Short
这解释了为什么您的代码使用
Short
而不是UShort
成功运行
无论如何,如果您真的需要在代码中使用UShort
,那么不应该将其设置为null,而是使用lateinit var
,这样就可以了。因为如果它不可为null,则编译后DA
属性的类型将是Short
var DA: UShort = 0u
//bytecode:
private S DA // S is JVM type for Short
// access flags 0x11
public final getDA-Mh2AYeg()S
...
// access flags 0x11
public final setDA-xj2QHRw(S)V
...
我想知道反射类和内联类之间是否存在缺陷。感谢您的解释!我想对我来说不使用UShort是最简单的。我很兴奋能找到这些,因为java中的某些东西——比如字节是有符号的——总是让我有点发疯,所以当我看到这些UShort和其他东西时,我有点太粗心了。我会想出一个解决办法。。。也许只是把它设为Int,因为0-65535正好适合Int。不客气。正如您所知,内联类只是一个奇特的包装器。它不会删除您遇到问题的符号位:D
var DA: UShort = 0u
//bytecode:
private S DA // S is JVM type for Short
// access flags 0x11
public final getDA-Mh2AYeg()S
...
// access flags 0x11
public final setDA-xj2QHRw(S)V
...