我在hashCode
类的AbstractORM
中有以下方法覆盖:
var _id = Random().nextLong()
override fun getId() = _id // AbstractORM class implements an interface that defines this method getId()
override fun hashCode() = getId().hashCode()
突然开始抛出以下异常:
FATAL EXCEPTION: main
java.lang.NoSuchMethodError: java.lang.Long.hashCode
at com.company.ormlite.AbstractORM.hashCode(AbstractORM.kt:271)
at java.util.HashMap.put(HashMap.java:390)
at java.util.HashSet.add(HashSet.java:95)
at kotlin.collections.ArraysKt___ArraysKt.toCollection(_Arrays.kt:6518)
at kotlin.collections.ArraysKt___ArraysKt.toSet(_Arrays.kt:6853)
at kotlin.collections.SetsKt__SetsKt.setOf(Sets.kt:32)
at com.company.android.tna.orm.DataManager.getTables(DataManager.kt:16)
at com.company.android.tna.orm.DataManager.getTables(DataManager.kt:10)
at com.company.android.core.utils.AbstractDataManager.create(AbstractDataManager.kt:25)
at com.company.android.core.utils.AbstractDataManager.start(AbstractDataManager.kt:44)
at com.company.android.core.utils.AbstractZKApplication.onCreate(AbstractZKApplication.kt:54)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:999)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4151)
at android.app.ActivityThread.access$1300(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1255)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
这让我傻眼了几个原因:
hashCode
方法,因为它是从Object
或Any
继承的。kotlin.Any.hashCode
,而不是java.lang.Long.hashcode
。非常感谢任何见解,提前谢谢。
答案 0 :(得分:14)
检查编译后的AbstractORM
类后,我发现了问题:较新的Kotlin版本为该行生成了不同的代码
getId().hashCode()
Kotlin 1.1.2生成以下代码:
Long.valueOf(this.getId()).hashCode()
而较新版本的Kotlin会生成其他代码:
Long.hashCode(this.getId())
问题是Android中的这种静态方法Long.hashCode(long)
仅在API 24(Android 7.0)之后可用,而我正在使用版本4.1(API 16)的Android设备上进行测试。
<击> 我正在通过手动计算哈希码来暂时修复,尽管我已经打开了一个问题here。
override fun hashCode() = (getId() xor getId().ushr(32)).toInt()
击> <击> 撞击>
如issue所述,切换到Kotlin编译器的Java 1.6目标会生成旧的兼容代码。
PS:我对这些Kotlin版本并不是100%肯定,请带上一粒盐。答案 1 :(得分:2)
我不确定如何解决您的问题,但我会尝试解释您为什么会遇到此异常。
在 Java 8 中,新的 static method 已添加到Long
类:
public static int hashCode(long value)
从那以后hashCode()
方法看起来像这样:
public int hashCode() {
return hashCode(this.value); // call Long.hashCode() static method
}
因此,您似乎对 Java 版本存在一些问题。
答案 2 :(得分:2)
我遇到了相同的问题,对我来说,解决方案是将build.gradle中的compileOptions
和kotlinOptions
都分配给版本 1.8
android {
...
// Configure only for each module that uses Java 8
// language features (either in its source code or
// through dependencies).
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// For Kotlin projects
kotlinOptions {
jvmTarget = "1.8"
}
}
引自Android开发者官方网站的Use Java 8 language features。
答案 3 :(得分:1)
如m0skit0建议的那样,覆盖hashCode()
函数对我有用。我实现了这一点:
override fun hashCode() : Int = id.toString().hashCode()
我在AndroidStudio中的Kotlin编译器设置为: