1. 报错
public class TestJava implements TestKotlin {
}
interface TestKotlin {
fun testKotlin() {
println("TestKotlin#testKotlin()")
}
}
提示需要实现 testKotlin() 方法.png
2. 简单解决
实现 testKotlin() 方法即可
public class TestJava implements TestKotlin {
@Override
public void testKotlin() {
// do nothing.
}
}
3. 追求卓越
如果你提供了一个 kotlin 的库给公众使用,那么公众就需要在每个地方都去实现一个空方法,是不是隐约听到 SB 作者 的骂声一片一片传来。
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += [
'-Xjvm-default', 'compatibility'
]
}
}
interface TestKotlin {
@JvmDefault
fun testKotlin() {
println("TestKotlin#testKotlin()")
}
}
public class TestJava implements TestKotlin {
}
使用 @JvmDefault 注解完美解决,前提是需要配置下 build.gradle 文件
参考
/**
*
* Specifies that a JVM default method should be generated for non-abstract Kotlin interface member.
*
* Usages of this annotation require an explicit compilation argument to be specified:
* either `-Xjvm-default=enable` or `-Xjvm-default=compatibility`.
*
* * with `-Xjvm-default=enable`, only default method in interface is generated for each @[JvmDefault] method.
* In this mode, annotating an existing method with @[JvmDefault] can break binary compatibility, because it will effectively
* remove the method from the `DefaultImpls` class.
* * with `-Xjvm-default=compatibility`, in addition to the default interface method, a compatibility accessor is generated
* in the `DefaultImpls` class, that calls the default interface method via a synthetic accessor.
* In this mode, annotating an existing method with @[JvmDefault] is binary compatible, but results in more methods in bytecode.
*
* Removing this annotation from an interface member is a binary incompatible change in both modes.
*
* Generation of default methods is only possible with JVM target bytecode version 1.8 (`-jvm-target 1.8`) or higher.
*
* @[JvmDefault] methods are excluded from interface delegation.
*/
@SinceKotlin("1.2")
@RequireKotlin("1.2.40", versionKind = RequireKotlinVersionKind.COMPILER_VERSION)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
@Deprecated("Switch to new -Xjvm-default modes: `all` or `all-compatibility`")
annotation class JvmDefault
附录
根据作者本地代码提示(kotlin 1.5.30 版本),该注解已被废弃,建议使用 -Xjvm-default all 或者 Xjvm-default all-compatibility 代替
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += [
'-Xjvm-default', 'all-compatibility'
]
}
}
interface TestKotlin {
fun testKotlin() {
println("TestKotlin#testKotlin()")
}
}
public class TestJava implements TestKotlin {
}
这样就不用每个方法上都去加 @JvmDefault 注解了
最后
鼓掌.png
网友评论