【发布时间】:2020-10-16 21:48:14
【问题描述】:
我有点高兴地偶然发现了Constable and the like in JDK 15。我基本明白了。
在把编译器理论全部玩了一遍,甚至稍微了解了一点之后,我发现我还有一个问题:谁调用了Constable的describeConstable()方法,什么时候调用的? Brian's presentation 似乎暗示它在编译时以某种方式被访问。由于对这些事情很天真,我期待它会出现在the usage page 下的jdk.compiler 或其他东西上。相反,the only consumption seems to be in the jdk.incubator.foreign package。 (显然,我知道它可能会被使用页面未公开的某些私人机器使用;因此我的问题。)
我将Thread.dumpStack() 放置在一个实现Constable 并返回Optional.ofNullable(null) 的哑类的describeConstable() 实现中,只是为了看看会发生什么……在编译或运行时什么都没有发生。
(我确实知道,在 JDK 12 之前,如果您想编写动态常量,则必须使用 ASM 或 ByteBuddy 或类似的东西。但在我天真的眼中,它看起来像 Constable 那样允许您的用户类“插入”Java 编译器并允许 it 为您编写常量。我也知道 java.lang.constant 中的类和方法主要是为编译器编写者准备的,但 Constable 似乎对我来说有点例外。最后,我显然明白我可以随时调用此方法,但这显然不是它的目的。)
编辑:(非常)感谢下面的一些非常有帮助和耐心的答案和 cmets,我想我开始明白了(我不是编译器的人)点应该很明显)。虽然我知道一旦存在X implements Constable 的实例,那么它从describeConstable() 返回的ContantDesc 必须由其他常量描述符(本身)制成,虽然我理解“常量工厂"(例如ClassDesc#of() 等)可能会在编译时调用,并且显然必须只接受其他常量作为它们可能需要的任何参数,我仍然不清楚 任意 X implements Constable 首先在编译期间被实例化,同时……它正在被编译(!),以便可以在编译时调用 describeConstable()。
请记住,这个问题的答案可能是我对一般编译器或它们在静态分析过程中遇到的各种问题的基本认识。我只看到一个实例方法 (describeConstable()) 需要在对象的实例 (X implements Constable) 上调用,并且为了拥有对象的实例,必须调用它的构造函数。我不清楚 Java 编译器如何知道如何使用其任意的、可能的多参数构造函数构造我的 X implements Constable,以便它可以在其上调用 describeConstable()。
【问题讨论】:
-
到目前为止,您所做的编辑也是我苦苦挣扎的部分。我见过的所有样本都使用任意方法进行引导,而不是
describeConstable。可能是 Oracle 的某个人会回复我们...