hot*_*key 18 java java-interop synthetic kotlin
我@JvmSynthetic在kotlin-stdlib中遇到了注释,我想知道它是什么,但不幸的是,它没有记录.
据我所知,将它应用于程序元素会将synthetic修饰符添加到相应的字节码元素.结果,该元素从Java变得不可见:
class MyClass {
@JvmSynthetic
fun f() { }
}
Run Code Online (Sandbox Code Playgroud)
Java代码中的某处:
MyClass c = new MyClass();
c.f() // Error: cannot resolve method f()
Run Code Online (Sandbox Code Playgroud)
但是在Kotlin代码中仍然可以看到相同的元素:
val c = MyClass()
c.f() // OK
Run Code Online (Sandbox Code Playgroud)
隐藏来自非Kotlin来源的声明是否有效使用@JvmSynthetic?它是预期用途吗?其他适当的用例是什么?
由于@JvmSynthetic隐藏了来自Java的函数,它们也无法在Java中被覆盖(当涉及abstract成员时,调用会产生AbstractMethodError).鉴于此,我可以@JvmSynthetic用来禁止在Java源代码中覆盖Kotlin类的成员吗?
小智 12
在普通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!";
}
}
Run Code Online (Sandbox Code Playgroud)
当SyntheticSample类访问该nested.syntheticString字段时,它确实调用了synthetic编译器生成的静态方法(类似名称access$100).
即使Kotlin公开了一个@JvmSynthetic能够"强制"创建合成方法的注释,我建议不要在普通的"用户"代码中使用它.合成方法是编译器制作的低级技巧,我们不应该在日常代码中依赖这些东西.我认为它可以支持标准库的其他部分,但如果你很好奇,你应该直接向JetBrains人询问(试试官方Kotlin论坛)
首先,要回答合成方法究竟是什么,让我们来看看Java 语言规范:
11.如果 Java 编译器发出的构造与源代码中显式或隐式声明的构造不对应,则必须将其标记为合成的,除非发出的构造是类初始化方法(JVMS §2.9)。
该@JvmSynthetic注释正是这么做的:防止源代码的访问。该方法仍将出现在反射中,然后被标记为合成。
更准确地说,来自Kotlin 文档(重点是我的):
@JvmSynthetic
ACC_SYNTHETIC在 Java 字节码中的注释目标上设置标志。在编译时,Java 源无法访问合成目标,而 Kotlin 源仍然可以访问。将目标标记为合成是二进制兼容的更改,已编译的 Java 代码将能够访问此类目标。
此注释适用于API 设计人员需要对 Java API 隐藏 Kotlin 特定目标,同时将其保留为 Kotlin API 的一部分的极少数情况,因此生成的 API 对两者都是惯用的。
如上一段所述,它@JvmSynthetic是一种 API 设计工具,可让库编写者避免自动生成 Java 等价物。最流行的用例可能是 Kotlin 独有的特性,例如运算符重载、componentN()方法或属性,它们可能有更惯用的方式在 Java 中公开。
值得注意的是,这个注解的目标是属性设置器/获取器、函数和字段——基本上所有在 Java 中转换为方法的东西。
@Target([
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.FIELD])
annotation actual class JvmSynthetic
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1525 次 |
| 最近记录: |