我有点高兴地偶然发现Constable了 JDK 15 之类的东西。我基本明白了。
在翻遍了所有编译器理论甚至理解了一点之后,我发现我仍然有一个问题:谁调用 aConstable的describeConstable()方法,何时调用? Brian 的演示似乎暗示它在编译时以某种方式被访问。对这些事情太天真了,我期待它出现在使用页面下jdk.compiler或其他东西中。相反,唯一的消耗似乎是在jdk.incubator.foreign包中。(显然,我知道它可能会被使用页面未公开的某些私人机器使用;因此我的问题。)
我放在Thread.dumpStack()一个describeConstable()哑类的实现,实现Constable和回报Optional.ofNullable(null)只是为了看看会发生什么,......什么都没有发生在编译期或运行时。
(我确实知道,在 JDK 12 之前,如果您想编写动态常量,您必须使用 ASM 或 ByteBuddy 或类似的东西。不过,在我幼稚的眼中,它看起来像是Constable允许您的用户类“插入”Java编译器并允许它为你做不断的写作。我也知道里面的类和方法java.lang.constant主要是为编译器编写者准备的,但Constable在我看来有点例外。最后,我显然明白我可以调用我希望随时使用这种方法,但这显然不是它的目的。)
编辑:(非常)感谢下面一些非常有帮助和耐心的答案和评论,我想我开始明白了(我不是编译器,这点应该很明显)。虽然我知道一旦一个X implements Constableexists的实例,那么ContantDesc它从它的返回describeConstable()必须由其他常量描述符(本身)组成,虽然我知道ClassDesc#of()可以在编译时调用“常量工厂”(例如等等),显然必须只接受其他常量作为他们可能需要的任何参数,我仍然不清楚 X implements Constable首先在编译期间如何实例化任意对象,而......它正在被编译(!)describeConstable() 可以在编译时调用它。
请记住,这个问题的答案可能是我所缺少的关于编译器的基本信息,或者他们在静态分析期间遇到的各种问题。我只看到一个实例方法 …
我有一个问题并不是那么大,但仍然让我思考如何使用Java构造函数和方法.
我有一个代表我声明最终的半径的常量,并且还公开供所有人查看.当我永远不会改变半径时,我不希望我的代码充斥着getRadius()方法.
我想在构造函数中初始化常量,因为我想在分配半径之前应用某些条件,必须满足某些条件.但是,这些条件确实占用了一些空间,我想将它们放在其他方法中,以使构造函数更清晰.
整个事情最初看起来像这样
public MyProblematicClass {
public final int radius;
public MyProblematicClass(... variables ...) {
if(... long criteria ...) {
radius = n;
}
}
}
Run Code Online (Sandbox Code Playgroud)
而且我喜欢它最终会像
public MyProblematicClass {
public final int radius;
public MyProblematicClass(... variables ...) {
this.setRadiuswithCriteria(criteria);
}
private void setRadiuswithCriteria(criteria crit) {
if(... crit ...) {
radius = n;
}
Run Code Online (Sandbox Code Playgroud)
我知道我可能会将该方法用于其他目的,这就是给我一个'空白字段RADIUS的原因可能尚未初始化,所以我想知道是否有办法添加一个只会是用于建造者,为清洁起见.
今天我面临一种奇怪的行为,我无法弄清楚为什么.
想象一下,我们在Java中的典型类中有一个final变量.我们可以立即或在类构造函数中初始化它,如下所示:
public class MyClass {
private final int foo;
public MyClass() {
foo = 0;
}
}
Run Code Online (Sandbox Code Playgroud)
但我不知道为什么我们不能在构造函数foo中调用方法并在该方法中初始化,如下所示:
public class MyClass {
private final int foo;
public MyClass() {
bar();
}
void bar(){
foo = 0;
}
}
Run Code Online (Sandbox Code Playgroud)
因为我认为我们仍处于构造函数流程中,但尚未完成.任何暗示都将受到热烈的赞赏.