繁体   English   中英

什么是@JvmSynthetic在Kotlin中的用途?

[英]What's the intended use of @JvmSynthetic in Kotlin?

我在kotlin-stdlib中遇到过@JvmSynthetic注释,我想知道它是什么,但不幸的是,它没有记录。 (UPD:就在那一刻)

据我所知,将它应用于程序元素将synthetic修饰符添加到相应的字节码元素。 结果,该元素从Java变得不可见:

class MyClass {
    @JvmSynthetic
    fun f() { }
}

Java代码中的某处:

MyClass c = new MyClass();
c.f() // Error: cannot resolve method f()

但是在Kotlin代码中仍然可以看到相同的元素:

val c = MyClass()
c.f() // OK

隐藏来自非Kotlin来源的声明是否有效使用@JvmSynthetic 它是预期用途吗? 其他适当的用例是什么?

由于@JvmSynthetic隐藏了Java中的函数,因此它们也无法在Java中被覆盖(当涉及abstract成员时,调用会导致AbstractMethodError )。 鉴于此,我可以使用@JvmSynthetic来禁止在Java源代码中覆盖Kotlin类的成员吗?

在普通Java中, synthetic方法由javac编译器生成。 通常,当封闭类访问使用private修饰符指定的字段时,编译器必须在嵌套类上创建合成方法。

给出java中的以下类:

public final class SyntheticSample
{
    public static void main(final String[] args)
    {
        SyntheticSample.Nested nested = new SyntheticSample.Nested();
        out.println("String: " + nested.syntheticString);
    }

    private static final class Nested
    {
        private String syntheticString = "I'll become a method!";
    }
}

SyntheticSample类访问nested.syntheticString字段时,它确实调用了编译器生成的静态synthetic方法(名称类似于access$100 )。

即使Kotlin公开了一个能够“强制”创建合成方法的@JvmSynthetic注释,我建议不要在普通的“用户”代码中使用它。 合成方法是编译器制作的低级技巧,我们不应该在日常代码中依赖这些东西。 我认为它可以支持标准库的其他部分,但如果你很好奇,你应该直接向JetBrains人询问(试试官方Kotlin论坛

首先,要回答什么合成方法实际上 ,让我们来看看Java语言规范

11.如果Java编译器发出的构造与源代码中显式或隐式声明的构造不对应,则必须将其标记为合成构造,除非发出的构造是类初始化方法(JVMS§2.9)。

@JvmSynthetic批注就是这样做的:阻止从源代码访问。 该方法仍将出现在反射中,然后标记为合成。

更确切地说,从Kotlin文档 (强调我的):

@JvmSynthetic

在Java字节码中的带注释的目标上设置ACC_SYNTHETIC标志。

在编译时,Java源代码无法访问合成目标,而Kotlin源代码仍可访问。 将目标标记为合成是二进制兼容的更改,已编译的Java代码将能够访问此类目标。

此注释适用于API设计人员需要从Java API隐藏Kotlin特定目标同时将其保留为Kotlin API的一部分的极少数情况,因此生成的API对于两者都是惯用的。

如上一段所述, @JvmSynthetic是一个API设计工具,它允许库@JvmSynthetic器避免自动生成Java等价物。 可能最流行的用例是仅Kotlin的特性,例如运算符重载, componentN()方法或属性,这些特性可能在Java中暴露出更惯用的方式。

值得注意的是,这个注释的目标是属性设置器/ getter,函数和字段 - 基本上所有用Java翻译成方法的东西。

@Target([
    AnnotationTarget.FUNCTION,
    AnnotationTarget.PROPERTY_GETTER,
    AnnotationTarget.PROPERTY_SETTER,
    AnnotationTarget.FIELD])
annotation actual class JvmSynthetic

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM