美文网首页
Android java 实现 kotlin 含有默认方法的接口

Android java 实现 kotlin 含有默认方法的接口

作者: 雁过留声_泪落无痕 | 来源:发表于2021-09-23 16:50 被阅读0次

    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 文件

    参考


    1. JvmDefault - Kotlin Programming Language (kotlinlang.org)
    2. JvmDefault 源码
    /**
     *
     * 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

    相关文章

      网友评论

          本文标题:Android java 实现 kotlin 含有默认方法的接口

          本文链接:https://www.haomeiwen.com/subject/jajogltx.html